type
status
date
slug
summary
tags
category
password
icon
BlockCanary 的原理
在调⽤ start() 时,通过调⽤主线程的 Looper.setMessageLogging() ⽅法,为 Looper 的 mLogging 成员变量赋值。
在 Looper 死循环中, println ⽅法分别会在
dispatchMessage(msg)
之前和之后被调
⽤。所以通过⾃定义 Printer 对象,我们就可以获得 dispatchMessage 的耗时,从⽽判断出是否有应⽤卡顿。
同时 BlockCanary 还会在⼦线程中执⾏⼀个获取主线程堆栈信息的定时任务,这个任务会在
dispatchMessage 结束的时候被移除。
BlockCanary 的缺陷
- 依靠定时获取堆栈的⽅法,定位不够精准。
println
⽅法中会拼接字符串对象
获取⽅法运⾏时间
- Hugo
- TraceView
- Systrace
- 使⽤ python 终端命令⽣成 Trace ⽂件 官⽅⽂档
- 在⾼版本中,可以通过 System tracing ⽣成 trace ⽂件,⽣成的⽂件可以在 这⾥ 在线分析
在代码中主动做标记:

Trace 分析界⾯常⽤操作:
- W :放⼤ (加 Shift 效果加倍)
- S :缩⼩ (加 Shift 效果加倍)
- A :左移
- D :右移
- M:标记当前选中的时间线
- 1 :选中区域
- 2 :拖拽
- 3 :放⼤缩⼩
- 4 :裁剪时间线
查看函数时间:
查看绘制帧:
绿⾊表示在 16ms 内完成,⻩⾊和红⾊表示超过 16 ms。
查看绘制状态:
- 绿⾊(Running)表示运⾏中
- 蓝⾊(Runnbale)表示可以被运⾏但是没有分配到 CPU
- 灰⾊(⽩⾊)(Sleeping)
- 桔红⾊(Uninterruptible Sleep)表示在执⾏ I/O 操作
⾃定义 Plugin
代码已上传到 github
重点:在 transform ⽅法中,遍历⽂件夹。
然后通过 ASM 对 class ⽂件进⾏处理
ASM 是一个 Java 字节码操纵框架,它能被用来动态生成类或者增强既有类的功能。ASM 可以直接产生二进制 class 文件,也可在类被加载入虚拟机之前动态改变类行为, ASM 从类文件中读入信息后,能够改变类行为,分析类信息,甚至能根据要求生成新类。目前许多框架如 cglib、Hibernate、 Spring 都直接或间接使用 ASM 操作字节码。
查看 ASM 字节码的⼯具 (两个都可以)

微信开源方案:
com.tencent.matrix.plugin
其中包含 TrackCanary简单说下腾讯开源库 Matrix 获取每个方法耗时的大致原理。
通过 ASM 在字节码中给每个方法进入和退出时插入记录代码,进入/退出方法,方法标识,方法时间会被转为 long 类型记录到数组中,后续分析就可以根据方法标识从中取出数据,分析耗时
在方法调用前后插入 i/o 代码,方法调用时记录,在 dispatchMessage 耗时超阈值的时候,查表找出对应方法
简单说下 BlockCanary 实现的原理?
通过调用主线程的 Looper 的 setMessageLogging 方法,传入一个 printer,以此在 disptachMessage 前后插入代码,记录 dispatchMessage 的耗时。
同时,在出现耗时方法时,通过获取线程堆栈的方式,获取主线程当前的调用栈以此来获得耗时方法
简单说下你知道的有哪些分析程序运行时间的方案。
Hugo,TraceView,Systrace,TraceCanary,插桩等
- 作者:shuouyang
- 链接:https://notion-tree.vercel.app/article/7929d3da-3cb4-48a7-9722-6755bed7a29c
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。