安卓卡顿排查步骤

接到组长下发的书城卡顿排查任务,学习了两个工具,记录一下排查过程,以后可以模仿此步骤,进行页面卡顿检测

下面两个工具地址,都在DDMS中,位置如下:your\way\to\androidsdk\tools\monitor.bat,双击即可打开

一、Systrace

Systrace 允许您在系统级别收集和检查设备上运行的所有进程的计时信息。 它将来自Android内核的数据(例如CPU调度程序,磁盘活动和应用程序线程)组合起来,以生成HTML报告。

抓取Systrace的方法

1.连接手机,勾选需要分析的进程,点击右侧箭头处的图标

2.弹框中,勾选需要分析的参数,点击OK,操作app中感觉卡顿的部分,5秒钟后,可以在弹框中配置的地方,找到生成的trace.html

还有一种使用命令行的方式进行抓取,大家可能会碰到某些问题,我这边已经踩过坑了,按照链接步骤操作即可
命令行方式抓取Systrace

分析Systrace的方法

使用Chrome打开trace.html文件,有几处需要关注,1.Alerts,2.Frames

控制键如下:

g键,可开启60fps的红色参考线。
w键,放大
s键,缩小
a键,左移
d键,右移
f键,放大选中的帧

Frames中可以看到一个个F,代表了每一帧。绿色代表了16ms中绘制了一帧,黄色和红色代表了超过16ms,发生了丢帧。

我们可以先看Alert框中的内容,这里面是系统给我们分析出所有超时帧的问题

可以看出,7帧发生了测量布局超时,17帧发生了延时,10帧发生了saveLayer超时,3帧draw超时,72帧设置了Alpha

一般我们会分析红色的帧。我们选一个比较有特点的帧看一下,依次按下m键,f键。屏幕上可以看到下图

最上面可以看到这一帧耗时39.789ms,差不多3帧的时间,下方Alert提示,这一帧中发生了4次saveLayer操作。这个可能是发生在CoverImageView的draw方法中

        canvas.getClipBounds(bounds);
        boundsf.set(bounds);
        super.onDraw(canvas);
        canvas.saveLayer(boundsf, maskXferPaint, Canvas.ALL_SAVE_FLAG);
        canvas.drawARGB(0, 0, 0, 0);
        canvas.drawRoundRect(boundsf, radius, radius, canvasPaint);
        canvas.restore();

谷歌大会时开发人员讲到,Flutter中不建议用clipPath,saveLayer的,他们优化掉了这个操作。我们换成了Glide,可以研究一下,去掉CoverImageView这个耗时的类

还有一个被我优化掉的点是,双排10书封。发现DrawFrame时间超长。猜测可能是加载图片导致。修改为,滑动列表时,暂停图片加载,列表暂停时,加载图片。解决了问题。

从这个烽火图上还可以看出很多问题建议。
比如:在动画过程中避免进行layout操作

比如:因耗时操作导致的丢帧,这个可以结合第二部分的TraceView一起看

可以看出,在这一帧中,上方的cpu模块,有很多beacon线程在做操作,推测可能是在进行曝光上报。尤其是多书封的上报,代码中整了个for循环,一本发一次。可以考虑优化成一次上报,不过这个需要数据和后台同学的共同努力。暂时只能这样了。
从烽火图中可以看到很多问题,需要逐帧的进行查看,具体问题具体分析。

二、TraceView

TraceView 是 Android SDK 中内置的一个工具,它可以加载 trace 文件,用图形的形式展示代码的执行时间、次数及调用栈,便于我们分析。

附上参考文章
TraceView是啥

抓取Trace的方法

有多种抓Trace的方法,当然是介绍最简单的方式。

1.连接手机,勾选需要分析的进程,点击左侧箭头处的图标开始抓

2.操作app中感觉卡顿的部分,然后再次点击图标,暂停抓取。几秒后会展示出trace的图形化界面

分析Trace的方法

先用网上的一个图介绍下参数都是什么意思

使用TraceView查看耗时,主要关注Calls+Recur Calls/Total和Cpu Time/Call这两个值,关注调用次数多和耗时久的方法

程序优化两点要素:
一是调用次数不多,但每次调用却需要花费很长时间的函数。这个可以从Cpu Time / Call反映出来。
一个是那些自身占用时间不长,但调用却非常频繁的函数。这个可以从Calls + Recur Calls / Total反映出来。

浩哥还介绍了一个适应我们自己程序的点,就是直接搜索attachView,分析我们card列表中的耗时操作有哪些。放个图看看

从图上可以看出,attachView方法被调用23次,总时长230ms,每个方法稳定在10ms左右。log.d调用次数最多,其次是单书封BaseXLCover,单书封card,点击条目可以查看具体的内容

可以看出,我们整体的性能还是比较好的,大家都很棒。如果有性能问题的话,可以参考下面的链接,学习寻找的方法Trace图怎么看

备注

还有很多没有写的性能学习资料,大家有时间可以去官网看看谷歌官网Trace,学习一下AS中的Profile,以及SysTrace的替代品Perfetto