当应用发生卡顿时,我们如何得知是什么原因导致的呢?是机器性能差,还是代码问题,抑或是其他应用抢占CPU资源问题呢?特别是概率比较低,难以复现的卡顿问题。使用BlockCanary库可以帮助你记录应用发生卡顿时的堆栈信息和CPU信息。
BlockCanary
用法
dependencies {compile 'com.github.markzhai:blockcanary-android:1.5.0'// 仅在debug包启用BlockCanary进行卡顿监控和提示的话,可以这么用debugCompile 'com.github.markzhai:blockcanary-android:1.5.0'releaseCompile 'com.github.markzhai:blockcanary-no-op:1.5.0'
}
在Application中
public class DemoApplication extends Application {@Overridepublic void onCreate() {// 在主进程初始化调用BlockCanary.install(this, new AppBlockCanaryContext()).start();}
}
详情参考《Android Performance Monitor》
原理
BlockCanary是如何做到监测到应用卡顿,并及时dump出堆栈信息的呢?
- 一个Android应用进程通过zygote进程fork出来的,进程创建完成后,DVM就会执行ActivtyThread中的main()方法,而在main()方法中主要是为主线程创建Looper循环器,并开始循环,从下面的代码可以看出。
- 自此,主线程的Looper循环器进入无限循环,不断从消息队列中取出消息,一条条地进行处理。通过查看Looper.loop()方法的代码可以看出,在调用dispatchMessage()方法处理消息前后,都会调用logging.println()方法,而这个logging对象可以通过Looper类的setMessageLogging()进行设置。因此,我们只需要自定义实现Printer接口的类(对应BlockCanary库中的LooperMonitor类),然后创建该类的实例,并通过setMessageLogging()方法设置到主线程的Looper循环器中。
BlockCanary扩展库——BlockCanaryEx
BlockCanaryEx主要是在BlockCanary的基础上,提供了更加详细的dump信息。
具体用法参考BlockCanaryEx
参考资料
- Android Performance Monitor
- BlockCanaryEx)
- BlockCanary — 轻松找出Android App界面卡顿元凶 | markzhai’s home