在Android中,Handler是一个使用的非常频繁的东西,输入事件机制和系统状态,都通过Handler来进行流转,而在Handler中,有一个很少被人提起但是却很有用的东西,那就是IdleHandler,它的源码如下。
代码语言:javascript复制/**
* Callback interface for discovering when a thread is going to block
* waiting for more messages.
*/
public static interface IdleHandler {
/**
* Called when the message queue has run out of messages and will now
* wait for more. Return true to keep your idle handler active, false
* to have it removed. This may be called if there are still messages
* pending in the queue, but they are all scheduled to be dispatched
* after the current time.
*/
boolean queueIdle();
}
从注释我们就能发现,这是一个IdleHandler的静态接口,可以在消息队列没有消息时或是队列中的消息还没有到执行时间时才会执行的一个回调。
这个功能在某些重要但不紧急的场景下就非常有用了,比如我们要在主页上做一些处理,但是又不想影响原有的初始化逻辑,避免卡顿,那么我们就需要等系统闲下来的时候再来执行我们的操作,这个时候,我们就可以通过IdleHandler来进行回调。
它的使用也非常简单,代码示例如下。
代码语言:javascript复制Looper.myQueue().addIdleHandler {
// Do something
false
}
在Handler的消息循环中,一旦队列里面没有需要处理的消息,该接口就会回调,也就是Handler空闲的时候。
这个接口有返回值,代表是否需要持续执行,如果返回true,那么一旦Handler空闲,就会执行IdleHandler中的回调,而如果返回false,那么就只会执行一次。
❝当返回true时,可以通过removeIdleHandler的方式来移除循环的处理,如果是false,那么在处理完后,它自己会移除。 ❞
综上,IdleHandler的使用主要有下面这些场景。
- 低优先级的任务处理:替换之前为了不在初始化的时候影响性能而使用的Handler.postDelayed方法,通过IdleHandler来自动获取空闲的时机。
- Idle时循环处理任务:通过控制返回值,在系统空闲时,不断重复某个操作。
但是要注意的是,如果Handler过于繁忙,那么IdleHandler的执行时机是有可能被延迟很久的,所以,要注意一些比较重要的处理逻辑的处理时机。
在很多第三方库里面,都有IdleHandler的使用,例如LeakCanary,它对内存的dump分析过程,就是在IdleHandler中处理的,从而避免对主线程的影响。