MessageQueue中的IdleHandler
在Android中,Handler是我们最常用的消息处理类,也是系统中非常重要的类,所以它的原理我们也应该十分的清楚了解,所以Handler,Looper,MessageQueue成了我们必须学习和理解的东西,但是其中有一个接口很少被提及和使用,那就是IdleHandler。
IdleHandler一、源码解析
根据注释我们很清楚的知道,这个接口方法是在消息队列消息队列全部处理完成后或者是在阻塞的过程中等待更多的消息的时候调用的,返回值绝对了处理一次后是否保存这个接口。虽然注释很清楚,但是我们更多的应该是要知道他是怎么处理的,所以看源码:
先看下接口的添加和删除:
添加接口 删除接口从上面所贴出的源码中我们可以得到两点:
1、添加和删除是线程安全的
2、通过查找可以得知mIdleHandlers是一个ArrayList,因此这个接口是可以重复添加的,不必担心被替换问题
接下来我们看看接口是如何被调用的,通过源码查找,我们知道了它是在next()方法中调用的,同时我们也知道,这个方法也是消息队列用来循环消息的地方,由于方法比较长,我就只贴部分关键源码:
其实这部分源码注释都已经很清楚了
第一部分应该算是条件判断,首先判断的是是不是第一次,pendingIdleHandlerCount的初始化为-1,其次判断的是有没有IdleHandler接口,如果没有的话就是阻塞
第二部分是接口处理,主要是接口的调用以及判断是不是接口只运行一次就不需要了,最后是设置判断的条件
二、系统源码中的IdleHandler使用
通过上面的源码分析可以找到,他是空闲时调用,这一定是一个非常有用的接口。于是在系统源码中查找它的使用,发现了一点小小的惊喜,在这里分享给大家
在对源码的学习中,我发现了IdleHandler的踪迹,他出现的位置也是很关键的位置,在ActivityThread中,学习过源码的同学都知道,这是一个非常重要的类,因为其实这才算是一个程序的入口,额,有点远了,有兴趣的同学可以自己去看下这个类,不多说,上源码
上面的代码很简单,主要是添加和移除接口,以及接口实现,但是接口实现的时候有个小惊喜啊,看方法名称就很意外doGcIfNeeded(),这个地方涉及到回收。大家都知道系统会自动回收,但是什么时候回收,哪个地方回收的,一直都很模糊,现在总算知道一点了,但是这仅仅是一个方面的回收,不要当成全部
回收这个也很简单了,主要是2次回收有最小时间间隔,就不多说了
Tips:
如果没看过ActivityThread可能不知道上面的Looper.myQueue()指的是哪个Looper这里给大家说明下,还是先上源码:
ActivityThread.java使用过Looper的人应该都很明白这个,从代码中可以看出,这个地方准备的是主线程,所以回收添加的Looper是MainLooper,另外大家不会忘了main方法吧:-D
三、其他源码中的使用
请大家原谅我年轻,阅读的开源代码比较少,也可能是其他的开源项目中没有这样的需求,所以只在Glide中看到过这个接口的使用,Google不愧为最了解源码的啊,源码贴给大家
Engine.javaGlide是一个面向接口的开源项目,而且写的很高明,本人的JAVA功底比较薄弱,所以看起来有点吃力,就不给大家具体解释了,大家有兴趣可以自己去查看,同时也希望有大神分析下Glide的源码,膜拜。