- idleHandler的作用和调用方式?
- idleHandler的使用场景?
- idleHandler的实现原理?
首先看一下IdleHandler接口的定义,从上面的定义可以看到,IdleHandler的触发时机是当前线程的消息队列中没有消息,或消息队列中的消息尚未到处理的时间,这时就会触发IdleHandler的queueIdle方法。
IdleHandler的用法
需要注意,queueIdle的返回值是boolean类型,当queueIdle返回true,将会在每次空闲的时候都会调用queueIdle,反之要是返回false,则只调用一次。
上面是addIdleHandler方法,可以看到IdelHandler会被添加到mIdleHandlers中,等待处理。
我们知道线程在消息监听的时候会通过Looper.loop()函数循环监听消息队列,在loop方法中, 会阻塞在queue.next()的地方从消息队列中读取最新可处理消息:
上面是queue.next()方法,我们知道nextPollTimeoutMillis是下一次读取消息的时间,在等待nextPollTimeoutMillis时间之后,要是mMessageQueue中没有可处理消息,则会向下读取IdelHandlers队列中IdleHandler的个数,当youIdleHandler要处理的时候,会遍历调用每个IdleHandler的queueIdle方法,在调用的时候,会判断IdleHandler的queueIdle方法的返回值,要是返回了false,会将该IdleHandler从队列中移除,这样下次线程进入无可处理消息的时候,就不会再通知该IdleHandler了。
IdleHandler的使用场景
1. GC
上面的GCIdle,系统会将它加入到主线程的Handler中,当主线程消息队列处于休眠状态的时候尝试出发一次GC,我们看到GcIdler的queueIdle返回false,表示该GcIdler只会触发一次。
2. LeakCanary检测Activity内存泄漏
LeakCanary会在Activity调用onDestroy之后,监听该Activity是否被正常回收,但是监听Activity的回收情况是比较耗性能的,有可能影响到主线程UI的渲染,LeakCanary为了避开主线程UI渲染,就会使用IdleHandler,在主线程空闲的时候触发监听。
3. Activity中的耗时操作
当我们打开一个Activity的时候,在onCreate中有可能会进行一些耗时但又不那么紧急的操作,这些操作可以延后一段时间执行,此时我们就可以使用IdleHandler实现,等主线程中消息处理完成处于休眠状态的时候,在IdleHandler的queueUdle方法中再触发这些操作。