概要
测试一个Android App的卡顿率(流畅性、顺滑度)的方法有很多,不同的厂和团队有他们不同的玩法,有的用高速摄像机去评估,有的用肉眼主观感受,有的通过获取获取底层数据的去评估,也有的像本文章一样,通过Android官方推荐的方法来测试界面性能。本文将会通过一个例子,闭环从数据采集到图表结果生成。
数据准备
设置准备
本方法仅仅适用于Android 6.0(API 级别)或以上的机器使用。首先我们打开手机的【开发者选项】,从里面找到【GPU呈现模式分析】或者【HWUI呈现模式分析】,点击它,并选择如下图提示的选项。
这样我们就可以从adb shell dumpsys gfxinfoframestats 中获取我们需要分析卡顿的具体详细信息,如果你没打开上图的选项,那么你将无法获得具体的Draw、Prepare、Process、Execute信息。
数据提取
- 确认手机已经已经连接上你的电脑打开终端(或命令提示符)
- 打开任意你想测试的App
- 手动或者用录制好的脚本移动你想测试的界面(脚本操作稳定,更准确)
- 活动过程中输入命令行,把最近操作的120帧的监测数据写入C:\datas.csv 里面。
adb shell dumpsys gfxinfo com.tencent.qq framestats>c:\datas.csv
数据定义解释
用Excel打开datas.csv,我们可以看到一坨数据,大家不要慌,我会给大家解释重要字段的含义。
首先我们看看这组数据
很乱的感觉,不明觉厉吧?看看下表解释:
字段名 | 具体含义 |
Total frames rendered * | 本次dump搜集了帧信息的数量 |
Janky frames * | 上个字段中耗时超过16ms的数量(卡顿率%) |
XX th percentile | 消耗多少毫秒归类的百分比 |
Number Missed Vsync | 垂直同步失败的帧数量 |
Number High input latency * | 高输入延迟数-评估主线程负担大小 |
Number Slow UI thread * | 因UI线程上的工作导致超时的帧数 |
Number Slow bitmap uploads * | 因bitmap的加载耗时的帧数 |
Number Slow issue draw commands* | 因绘制导致耗时的帧数 |
Number Frame deadline missed | 错过截止日期的帧数 |
|
图表制作
制作耗时分布直方图表
对应datas.csv中“HISTOGRAM” 这个字段,可以制作耗时分布直方图表
还是使用Excel去实现,先把上图这样的东西分列,按照空格分列,得到如下格式:
然后复制分列后的产物,找个空表,点击鼠标邮件选择性粘贴中的转置粘贴,完成如下图效果:
选中这些数据,按上面提到的方法制作图表,选择堆积条形图即可:
通过这个图表,我们可以分析出这个过程中和丢帧率相关的分布。
制作Draw、Prepare、Process、Execute图表
先看看这四兄弟的含义:
- Draw:表示在Java中创建显示列表部分中,OnDraw()方法占用的时间。
- Prepare:准备时间
- Process:表示渲染引擎执行显示列表所花的时间,view越多,时间就越长
- Execute:表示把一帧数据发送到屏幕上排版显示实际花费的时间。其实是实际显示帧数据的后台缓存区与前台缓冲区交换后并将前台缓冲区的内容显示到屏幕上的时间。将上面四个时间加起来就是绘制一帧需要的时间,如果超过16ms就有掉帧了。
这里我们可以整理一下datas.csv中的Draw、Prepare、Process、Execute信息。我们使用Excel来整理,操作如下图:
分列完毕后,我们开始做Draw、Prepare、Process、Execute的图表,如下图:
好了,我们这样就拥有了关于Draw、Prepare、Process、Execute的图表了。
通过这个图表,我们可以分析出4个过程中最耗时是哪个过程,针对性去优化。
总结
做这些图,一是希望可以帮助我们分析问题,更直观找到问题的点,其次是可以帮我们归纳总结和成果展示,对程序员的积累成长事关重要。
参考
Android 渲染机制 Android系统每隔16ms发出VSYNC(Vertical Synchronization 垂直同步)信号,触发对UI进行渲染。如果系统发出VSYNC信号,而此时无法进行渲染,还在做别的操作,那么就会导致丢帧的现象,即屏幕的刷新速率大于帧率。之所以是16ms,是因为人眼与大脑之间的协作无法感知超过60fps(1000ms/60=16.6ms)的画面更新,超过60fps也是无意义的。