A transparent ui-block detection library for Android, app only needs one-line-code to setup.
Android Performance Monitor
A transparent ui-block detection library for Android, app only needs one-line-code to setup.
The naming is to pay respect to the great library LeakCanary, ui-related codes are modified from leakcanary’s ui part.
Getting started
You may choose how to assemble them as you like.
|
|
As this library uses getMainLooper().setMessageLogging()
, please check if you set it in your app (related issue https://github.com/moduth/blockcanary/issues/27)
Usage
Maximum log count is set to 500, you can rewrite it in your app int.xml
.
Monitor app’s label and icon can be configured by placing a block_canary_icon
drawable in your xhdpi drawable directory and in strings.xml
:
|
|
Implement your application BlockCanaryContext
context (strongly recommend you to check all these configs):
How does it work?
Blog in Chinese: BlockCanary.
Principle flow picture:
Screenshot
Contributors
This library is initially created by markzhai, and maintained under the organization moduth with nimengbo and zzz40500.
Special thanks to android-cjj, Mr.Bao, chiahaolu to contribute.
原理
熟悉Message/Looper/Handler系列的同学们一定知道Looper.java中这么一段:
|
|
是的,就是这个Printer - mLogging,它在每个message处理的前后被调用,而如果主线程卡住了,不就是在dispatchMessage里卡住了吗?
核心流程图:
该组件利用了主线程的消息队列处理机制,通过
并在mainLooperPrinter中判断start和end,来获取主线程dispatch该message的开始和结束时间,并判定该时间超过阈值(如2000毫秒)为主线程卡慢发生,并dump出各种信息,提供开发者分析性能瓶颈。
|
|
说到此处,想到是不是可以用mainLooperPrinter来做更多事情呢?既然主线程都在这里,那只要parse出app包名的第一行,每次打印出来,是不是就不需要打点也能记录出用户操作路径? 再者,比如想做onClick到页面创建后的耗时统计,是不是也能用这个原理呢? 之后可以试试看这个思路(目前存在问题是获取线程堆栈是定时3秒取一次的,很可能一些比较快的方法操作一下子完成了没法在stacktrace里面反映出来)。
总结
BlockCanary作为一个Android组件,目前还有局限性,因为其在一个完整的监控系统中只是一个生产者,还需要对应的消费者去分析日志,比如归类排序,以便看出哪些卡慢更有修复价值,需要优先处理;又比如需要过滤机型,有些奇葩机型的问题造成的卡慢,到底要不要去修复是要斟酌的。扯远一点的话,像是埋点除了统计外,完全还能用来做链路监控,比如一个完整的流程是A -> B -> D -> E, 但是某个时间节点突然A -> B -> D后没有到达E,这时候监控平台就可以发出预警,让开发人员及时定位。很多监控方案都需要C/S两端的配合。
Reference
[1]AndroidPerformanceMonitor
[2]BlockCanary — 轻松找出Android App界面卡顿元凶