「性能优化1.0」启动分类及启动时间的测量
「性能优化1.1」计算方法的执行时间
「性能优化1.2」异步优化
「性能优化1.3」延迟加载方案
「性能优化2.0」布局加载原理
「性能优化2.1」LayoutInflater Hook控件加载耗时
「性能优化2.2」获取布局的加载时间
「性能优化2.3」Choreographer检测丢帧
一、Choreographer检测丢帧
1.1、基本知识
在「性能优化2.1」LayoutInflater Hook控件加载耗时中提到屏幕绘制过程中涉及到两个基本概念:
- 屏幕刷新率:
屏幕刷新率代表屏幕在一秒内刷新屏幕的次数,这个值用赫兹来表示,取决于硬件的固定参数。这个值一般是60Hz
,即每16.66ms
系统发出一个 VSYNC 信号来通知刷新一次屏幕。
- 帧速率:
帧速率代表了GPU
在一秒
内绘制操作的帧数
,比如30fps/60fps。
1.2、Choreographer工作机制
那么我们怎么判断我们的页面卡顿呢?
在 Android API 16 中提供了 Choreographer
这个类,它会在每一帧绘制之前通过FrameCallback
接口的方式回调给上层,并且提供了当前帧开始绘制的时间(单位:纳秒)。
关于 Choregrapher 工作原理如下:
我们可以给 Choregrapher
注册一个 FrameCallback
回调,那么系统在每一帧开始绘制的时候,会通过 FrameCallback#doFrame(...)
回调出来。我们一般画面的 fps 一般是 60fps,在这个回调中计算对应的 fps 即可。
1.3、检测画面丢帧
private long mLastFrameTime;
Choreographer.getInstance().postFrameCallback(new Choreographer.FrameCallback() {
@Override
public void doFrame(long frameTimeNanos) {
if (mLastFrameTime == 0) {
mLastFrameTime = frameTimeNanos;
}
float diff = (frameTimeNanos - mLastFrameTime) / 1000000.0f;//得到毫秒,正常是 16.66 ms
if (diff > 500) {
double fps = (((double) (mFrameCount * 1000L)) / diff);
mFrameCount = 0;
mLastFrameTime = 0;
Log.d("doFrame", "doFrame: " + fps);
} else {
++mFrameCount;
}
Choreographer.getInstance().postFrameCallback(this);
}
});
2019-03-21 18:50:36.247 14594-14594/com.example.androidperfermance D/doFrame: doFrame: 58.590914260007196
2019-03-21 18:50:36.777 14594-14594/com.example.androidperfermance D/doFrame: doFrame: 58.5927162501806
2019-03-21 18:50:37.306 14594-14594/com.example.androidperfermance D/doFrame: doFrame: 58.59269529616955
2019-03-21 18:50:37.835 14594-14594/com.example.androidperfermance D/doFrame: doFrame: 58.59159872383989
2019-03-21 18:50:38.364 14594-14594/com.example.androidperfermance D/doFrame: doFrame: 58.59112378805347
2019-03-21 18:50:38.893 14594-14594/com.example.androidperfermance D/doFrame: doFrame: 58.592478772266325
2019-03-21 18:50:39.423 14594-14594/com.example.androidperfermance D/doFrame: doFrame: 58.594106233050574
2019-03-21 18:50:39.952 14594-14594/com.example.androidperfermance D/doFrame: doFrame: 58.592332095692704
2019-03-21 18:50:40.481 14594-14594/com.example.androidperfermance D/doFrame: doFrame: 58.59078155968632
2019-03-21 18:50:41.010 14594-14594/com.example.androidperfermance D/doFrame: doFrame: 58.59327502933717
2019-03-21 18:50:41.538 14594-14594/com.example.androidperfermance D/doFrame: doFrame: 58.59021584400927
2019-03-21 18:50:42.068 14594-14594/com.example.androidperfermance D/doFrame: doFrame: 58.59141014547363
2019-03-21 18:50:42.597 14594-14594/com.example.androidperfermance D/doFrame: doFrame: 58.59449739589946
2019-03-21 18:50:43.126 14594-14594/com.example.androidperfermance D/doFrame: doFrame: 58.59219240440056
2019-03-21 18:50:43.655 14594-14594/com.example.androidperfermance D/doFrame: doFrame: 58.592290188235125
二、总结
通过Choreographer
计算 FPS 可以检测画面是否卡顿。
记录于2019年3月21日