利用traceview优化Android应用流畅度

众所周知,屏幕刷新频率必须要达到60Hz,人眼才能感觉不到界面的卡顿。60Hz意味着界面每一帧的计算加渲染时间不能超过16ms,当某些业务逻辑比较耗时的时候,执行时间可能超过16ms的阈值,这时候给用户直观的感受就是界面卡顿。

traceview是安卓sdk提供的一个性能分析工具,能够收集函数的执行时间,以精确的分析系统的瓶颈所在。当我们遇到系统卡顿问题的时候,可以利用这个工具来进行分析。下边的篇幅就项目中一个真实的卡顿问题,来介绍traceview工具的使用。

在项目中遇到一个问题,滑动卡片的时候界面会出现卡顿,效果如下:

可以明显看到,卡片滑动的最后是有卡顿的,突然一下新的卡片就划进来了,中间的动画过程有缺失。

利用Android手机的自带工具,可以有更清楚的认识。开发者选项->GPU呈现模式分析,打开后,可以在屏幕上看到每一帧动画的耗时。

打开这个选项后,再操作手机,手机屏幕底下会出现一些柱形的图块,横坐标代表动画的每一帧,纵坐标代表这一帧的耗时,柱子的高度超过了绿色线就代表这一帧的耗时超过了16ms,会造成卡顿。我们没滑动一次卡片,就会发现一个远高于绿色线的柱状图形出现,也就是造成了卡顿。

上边只是定性的分析了为什么会造成卡顿,那怎么定量的分析呢,这时候traceview工具就派上用场了。

点击Android Studio上边的机器人小图标“Android Device Monitor”,再切换到DDMS,左边的面板上选择需要调试的进程,然后点击Start Method Profiling按钮,这时候工具开始对方法耗时进行记录。操作手机,滑动卡片后,再点击Stop Method Profiling按钮,这时候面板会呈现出记录期间每个函数执行的耗时。

最需要关注的数据是下边这张图

每一列的含义如下图

经过分析可以发现,notifyDataSetChanged这个函数执行时间为53.141ms,超过了要求的16ms阈值,所以问题就定位到这里了。解决方法的话,就比较简单了,想办法在切换卡片的时候去掉调用Adapter的notifyDataSetChanged调用,这里其实只是业务逻辑的修改优化。

优化后的效果,可以看到,再次切换的时候,已经几乎都在16ms以下。

优化后的动态效果图