性能指标
流畅性
FPS:SurfaceFlinger 合成次数
- FPS低可能是当前没有内容更新!
- 屏幕内若有多块显示区域(Surface),则我们的区域可能受影响
- 某些Surface合成不在SF中进行(Camera),则FPS无法衡量
FPS的计算,系统提供adb命令service call SurfaceFlinger 1013来获取从启动当前SF一共进行了多少次合成。
T1时间获取合成次数V1,T2时间获取合成次数V2
FPS = (V2-V1)/(T2-T1)
掉帧率
-
SF:修改系统属性debug.choreographer.skipwarning=1,则丢帧时都会打印日志。(限制:adb需要root权限)
setprop debug.choreographer.skipwarning 1
setprop ctl.restart surfaceflinger; setprop ctl.restart zygote -
SM:代码注入,监控Choreographer.FrameCallback,每调用一次就是一次渲染,相邻两次之间时间超过16ms则丢帧(限制:需要嵌入代码)
long lastTime = 0;
long thisTime = 0;
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
void startMonitor(){
Choreographer.FrameCallback frameCallback = new Choreographer.FrameCallback() {//系统绘帧回调
public void doFrame(long frameTimeNanos) {
thisTime = System.currentTimeMillis();
//累计流畅值
plusSM(thisTime);//当前秒的SM+1,如果当前秒数已经到下一秒,则将此SM值写入文件
//判别超时:
if (thisTime - lastTime > 40 && lastTime!=0){
Log.e("DDDD","frame超时"+(thisTime - lastTime)+"ms: "+ lastTime +"-"+ thisTime);
//saveBlockInfo(lastTime, thisTime);//此处保存卡顿信息
}
//设置下一帧绘制的回调
Choreographer.getInstance().postFrameCallback(this);//设置下次系统绘帧回调
lastTime = thisTime;
}
};
Choreographer.getInstance().postFrameCallback(frameCallback);
}
//保存当前SM值
private long nowTime =1;//当前的时间(ms)
private int sm = 1;
private void plusSM(long t){
if (nowTime ==1){
nowTime = t;
}
if (nowTime/1000 == t/1000){
sm++;
}else if (t/1000 - nowTime/1000 >=1){
//saveSMInfo(sm,t);//此处保存此时的流畅值SM
Log.e("DDDD","sm:"+sm);
sm=1;
nowTime = t;
}
}
- Janky frames: