Looper轮循的时候Printer 在每个message处理的前后被调用 logging.println,我们可以通过设置Printer计算Looper两次获取消息的时间差,如果时间太长就说明Handler处理时间过长直接把堆栈信息打印出来,就可以定位到耗时代码不过println 方法参数涉及到字符串拼接,考虑性能问题所以这种方式只推荐在Debug模式下使用。
基于此原理的开源库代表是:
取名为BlockCanary則是为了向LeakCanary致敬,顺便本库的UI部分是从LeakCanary改来的之后可能会做一些调整。
原理是这样比较Looper两次处理消息的时间差,比如大于3秒就认为卡顿了。
細节的话大家可以自己去研究源码
比如消息队列只有一条消息,隔了很久才有消息入队这种情况应该是要处理的,BlockCanary是怎么处理的呢
茬Android开发高手课中张绍文说过微信内部的基于消息队列的监控方案有缺陷:
这个我在BlockCanary 中测试,并没有出现此问题所以BlockCanary 是怎么处理的?简单汾析一下源码:
所以BlockCanary 能做到连续调用几个方法也能准确揪出耗时是哪个方法,是采用开启循环去获取堆栈信息并保存到LinkedHashMap的方式避免出現误判或者漏判。核心代码就先分析到这里其它细节大家可以自己去看源码。