本文只作总结,不写细节,可用于面试知识点快速复习。
需要深入了解细节的朋友请看完总结后带着问题去百度。
卡顿原因
出现卡顿的主要原因是主线程做了一些不该做的事,或者主线程做不了事情了,即主线程被某些耗时任务阻塞导致UI绘制的工作无法在下一帧到来前的16.66ms内(每一帧的时间间隔 =1s / 屏幕刷新频率60hz =16.66ms)完成,导致出现跳帧现象。
卡顿检测
方法 一
用反射的方法Choreographer.SKIPPED_FRAME_WARNING_LIMIT的值设置成1,日志过滤“Choreographer”,可以查看具体的跳帧数,类似于“Skipped 37 frames!”。
方法 二
在Choreographer中有个回调接口,FrameCallback。实现这个回调设置给Choreographer,每一帧被渲染的时候都会回调FrameCallback的doFrame方法,通过记录每一次doFrame的具体时间,通过log打印两次绘制时间的间隔,每一帧间隔的时间按照屏幕Vsync同步信号的频率应该为16.66ms,通过两次绘制的时间计算出跳帧数,然后查看全局日志观察在此跳帧时间段的方法调用堆栈,分析耗时方法。
方法 三
Android使用消息机制进行UI更新,UI线程有个Looper,在其loop方法中会死循环不断取出message,调用其绑定的Handler在UI线程执行。如果在handler的dispatchMesaage方法里有耗时操作,就会发生卡顿。 源码中在dispatchMesaage方法执行的前后都有Android预留的hook点用作性能分析,可以通过Looper.getMainLooper().setMessageLogging(new Printer())来跟踪每个message的处理时间,如果超过了16.66ms,说明发生了跳帧,那么则打印当前UI线程的堆栈信息进行分析。
最后在设备上执行怀疑会发生卡顿或者可能出现卡顿性能问题的交互流程,查看是否出现大量跳帧现象,分析耗时方法。