前言
在Android项目中,有时候我们需要去检测我们的应用是否发生卡顿,并且需要知道卡顿的点在哪里,这样我们才能去做优化。我上网查了好多资料,对比了好几种方案(如Matrix-TraceCanary
、BlockCanary
、BlockCanaryEx
、ArgusAPM
),最后选择使用Matrix-TraceCanary
来做卡顿检测监控,这是因为其他几种方案,要么是卡顿检测的粒度太大,无法知道具体卡顿的点(函数)在哪里;要么是框架太老了,很久没人维护,无法兼容现在的项目。接下来介绍下Matrix-TraceCanary
如何使用去定位到代码具体卡顿在哪个函数上。
Matrix-TraceCanary使用
1、在项目根目录下的 gradle.properties 中配置要依赖的 Matrix 版本号,我使用的是2.0.8
版本如:
2、在项目根目录下的 build.gradle 文件添加 Matrix 依赖,如:
3、接着,在 app/build.gradle 文件中添加 Matrix TraceCanary
模块的依赖(Matrix
除了TraceCanary
,还有好几个模块,因为我们这里只用来检测卡顿,所以只依赖TraceCanary
就可以),如:
4、需要继承下DefaultPluginListener
,这是用来接收Matrix
处理后的数据, 发生卡顿的相关数据就是在这个类返回给我们的,如:
如果检测到某个函数发生卡顿,这里就会被回调,具体的打印数据,类似如下,我们怎么通过这些数据来知道具体的卡顿点呢,这里有对这些数据的具体分析,TraceCanary的数据格式具体分析,现在我们先把TraceCanary
跑起来先。
java
**{
"machine":2015,
"detail":"ENTER",
"cost":3205,
"viewInfo":**{
"viewDeep":10,
"viewCount":6,
"activity":"TestFpsActivity"
},
"stack":"3,195,1,10\n1,33,1,58\n2,206,1,21\n3,161,1,16\n4,180,1,16\n5,169,1,16\n6,96,1,10\n7,98,1,10\n4,183,2,5\n5,211,6,0\n0,30,1,56\n",
"stackKey":"0,30,1,56\n",
"tag":"Trace_EvilMethod",
"process":"sample.tencent.matrix"
}
5、实现动态配置接口MatrixDynamicConfigImpl
:
6、在我们的Applicaiton
做初始化配置:
至此,我们的项目就成功接入TraceCanary
了,这时如果出现了某个函数发生卡顿(慢方法),我们就会收到相关的日志,如下,这里面的stack
就是慢方法发生时的具体堆栈,只要我们把它解析出来,就能知道具体的卡顿点了。
java
**{
"machine":2015,
"detail":"ENTER",
"cost":3205,
"viewInfo":**{
"viewDeep":10,
"viewCount":6,
"activity":"TestFpsActivity"
},
"stack":"3,195,1,10\n1,33,1,58\n2,206,1,21\n3,161,1,16\n4,180,1,16\n5,169,1,16\n6,96,1,10\n7,98,1,10\n4,183,2,5\n5,211,6,0\n0,30,1,56\n",
"stackKey":"0,30,1,56\n",
"tag":"Trace_EvilMethod",
"process":"sample.tencent.matrix"
}
stack数据解读分析
首先我们要知道,Matrix在编译时会生成一个methodMapping.txt
文件,这个文件记录了我们项目里所有方法的对应的id,我们拿到上面的stack
数据后,根据里面的数据来对照这张methodMapping
表格,就能知道具体是哪个方法了。
接下来讲下stack
里的数据具体表示什么意思:
java
**{
"stack":"
3,195,1,10\n
1,33,1,58\n
2,206,1,21\n
3,161,1,16\n
4,180,1,16\n
5,169,1,16\n
6,96,1,10\n
7,98,1,10\n
4,183,2,5\n
5,211,6,0\n
0,30,1,56\n",
}
这里我把数据换行了下,方便大家阅读,可以看到这里每一行都有4个数据如"3,195,1,10"
、"1,33,1,58"
、"2,206,1,21"
。
第一个数字代表:该方法在堆栈里的层级。
第二个数字代表:该方法在methodMapping
表格的id。
第三个数字代表:该方法被调用的次数。
第四个数字代表:该方法具体的耗时。
但是这里都有个很麻烦的点就是,我们在日志里拿到stack
数据后,我们需要去打开methodMapping
表,然后再一一去对应找相关的函数,这就比较麻烦,这里有一篇文章有比较快捷的方式,可以参考下: Matrix-TraceCanary 实际使用
TraceCanary的原理
网上介绍该原理的文章有很多,这里推荐几篇: