idleHandler详解
引言
前几天听同事讲有个 idleHandler 可以不和主线程其它工作争抢,可以做到空闲时候运行。当时想着这一块好像有点印象,记得在看 handler 源码时候看到 message 获取后面还有一段有关 idle 的代码,但是没有细看。这么一想,看源码还是不够仔细啊。虽然感觉这个实际上应该是在 message 为空的时候然后执行任务,思路挺简单明了的。但是今天正好有空,就好好看了一下源码,顺便查漏补缺。
详解
很轻松的找到 MessageQueue.IdleHandler,里面就一个接口方法 queueIdle 需要实现。看注释是返回 true 则保持,返回 false 则执行完删除。在 next 方法里可以看到当前没有要执行的消息或者还没到执行时间会往下查看有没有 idle 想要运行,有则运行,没有则返回。但里面仍然不能做耗时操作。这种适用场景挺少的。
建议慎用只在有些界面加载不急的时候可以放在这里。因为有的可能认为不怎么耗时,但是一用的多了就比较容易出 anr,而且还很难查,我这块不是耗时操作啊,为什么会 anr,可能就是因为大家都怎么想,结果可想而知,anr 会越来越多,也越来越难查,千万不要开这个头。其实既然加载或者初始化操作可以延迟,那为什么不直接放在子线程而要放在主线程。并且 android 系统内部使用也很少,主要是 gc 那块使用了,doGcIfNeeded()。
结论
所以 idleHandler 不是天堂,被滥用会导致很麻烦的 anr 问题,谨慎使用。
ps:感觉 android 有很多坑在,比如 Handler,本以为消耗很低啊,这么好用,等待过程还会被挂起,简直是神器。但是在深入下去会发现,其实 它底层用管道,通过监听来实现。一个 Handler 至少持有 4 个fd。虽然采用 epoll_wait 尽可能高效,但是以后也不敢在随意使用。毕竟看到 fd 超过限制的错误还是不少的。