Android性能测试之流畅度测试
流畅度测试简单的来说就是 Android 页面绘制。 Android 系统每秒 60hz, 也就是大约每 16ms 刷新一次界面。但是在我们使用 APP 过程中,经常会看到页面有卡顿,或者说丢帧的现象。也就是说可能此刻两个页面绘制的时间差超过 0.1S (人眼视觉残留 0.1S )。总的来说,就是页面
原理分析
在确定衡量指标之前,先来说 Android 的 UI 更新机制。
在 Android 版本更新过程中,发现在 Jelly Bean 中 Google 加入了一个 Project Butter ,用来解决严重影响 Android 口碑的问题之一“ UI 流畅性差”的问题。而 Project Butter 中主要引入了三个核心元素: VSYNC( 垂直同步 ) 、 Triple Buffer 和 Choreographer 。
VSync 是 Vertical Synchronization( 垂直同步 ) 的缩写,是一种在 PC 上很早就广泛使用的技术,可以简单的把它认为是一种定时中断。而在 Android 4.1(JB) 中已经开始引入 VSync 机制。 CPU 和 GPU 的处理时间都少于一个 VSync 的间隔,即 16.6ms 。如果每个间隔都有绘制的情况下,当前的 FPS 即为 60 帧。
VSync 机制就像是播放动画片 (60 帧 /s) 。每次都会播放画面,有的时候有人偷懒了,机器坏了,就会出现播放速度降低的状况。我们把这个播放速度叫做流畅度。
从 FPS& 丢帧到流畅度
实际上在很多 Android 的 App 中,很少有需要不断地去绘制的场景,很多时候页面都是静态的。也就是会出现这样的状况,虽然 1s 中 VSync 的 60 个 Loop 不是每个都在做绘制的工作, FPS 会比较低,但并不代表这个时候程序不流畅 ( 如我将 App 放着不动,实测 FPS 为 1) 。所以 FPS 较低并不能代表当前 App 在 UI 上界面不流畅,而 1s 内 VSync 这个 Loop 运行了多少次更加能说明当前 App 的流畅程度。所以,下面这 2 个指标比 FPS 更能代表当前的 App 是否处于流畅的状态。同样这 2 个指标更加能够量化 App 卡顿的程度:
1 )丢帧 (SF: Skipped Frame) :如上图 2 所示情况应该在 16.6ms 完成工作却因各种原因没做完,占了后 n 个 16.6ms 的时间,相当于丢了 n 帧。
2 )流畅度 (SM: SMoothness) :和丢帧相对,在 VSync 机制中 1s 内 Loop 运行的次数。
和丢帧相对 1s 内有 60 个 Loop 因为某几次工作时间超过了 16.6ms (丢帧),这样 Loop 就无法运行 60 次(理论最大值)。
当流畅度越小的时候说明当前程序越卡顿。
如何得到流畅度 (SM: SMoothness)
接着上面的结论,如果在这样的机制下每次 Loop 运行之前进行通知,记个数就好了。
很幸运我们在新的 Android 的那一套机制中找到了一个画图的打杂工 Choreographer 这个对象。根据 Google 的官方 API 文档描述中,它是用来协调 animations 、 input 以及 drawing 时序的,并且每个 Loop 共用一个 Choreographer 对象。
结论
通过如上原理分析可以得出结论:
1) Android 4.1 引入了 VSync 机制后,可以通过其 Loop 来了解当前 App 最高绘制能力。
固定每隔 16.6ms 执行一次 ( 这个值是一个静态变量,会根据系统版本不同而采用不同的值,目前测试版本是 16.6ms 这样最高的刷新的帧率就控制在 60FPS 以内 ) ;
如果没有以上事件的时候同样也会运行这样一个 Loop ;
这个 Loop 在 1s 之内运行了多少次,即可以表示当前 App 绘制的最高的能力,也就是 Android App 卡顿的程度;
另外,在一次 Loop 时如果执行时间超过了 16.6ms ,那么用多于 16.6ms 的时间除以 16.6ms ,即是当前 App 的丢帧 (SF: Skipped Frame) 。
2) 可以在 Choreographer 的回调 FrameCallback 中,按秒计数表示当前 App 的流畅程度,即流畅度 SM(SMoothness) 。
采用这样方式就可以在 App 内部观测当前 App 的流畅度了。并且在丢帧的地方打印 traceView ,就可以知道丢帧的大概原因,大概位置。定位代码问题。

查看13道真题和解析