这是我参与「第四届青训营 」笔记创作活动的第5天
性能耗时监控利用 HandlerThread 来检测耗时方法,在分发和处理消息开始前,发送一个延迟300毫秒的消息,如果分发和处理消息结束后还不到300毫秒,也就是消息处理时间小于300毫秒就会移除这个延迟300毫秒的消息,否则就会打印出这个耗时消息的栈轨迹。上图说明具体耗时方法在com.qxy.dousheng.ui.MainActivity中的第16行,也就是加载布局文件上。
首先想到的一个优化方案是动态构建布局, 使用kotlin 的DSL来改善构建代码的可读性,弃用 xml。onCreateViewHolder()执行在主线程,如果它执行耗时,势必会影响到也运行在主线程的绘制性能。
程序刚启动时丢帧较大,可以想到的优化方案有:
- 合理的使用异步初始化、延迟初始化、懒加载机制。
- 启动过程避免耗时操作,如数据库 I/O操作不要放在主线程执行。
- 类加载优化:提前异步执行类加载。
- 合理使用IdleHandler进行延迟初始化。
- 简化布局
总结
- 通过Looper的 Printer logging机制,计算Dispatch到Finish的耗时来评估消息执行耗时。
- 通过滑动的状态控制往Choreographer增加postFrameCallback回调的方式计算执行帧数。
- 造成丢帧主要有两个原因:一是遍历绘制 View 树以及计算屏幕数据超过了16.6ms;二是主线程一直在处理其他耗时消息,导致绘制任务迟迟不能开始(同步屏障不能完全解决这个问题)。
- Choreographer:使CPU/GPU的绘制是在VSYNC 到来时开始。Choreographer初始化时会创建一个表示对Vsync信号感兴趣的连接,当有绘制请求时通过postCallback方法请求下一次Vsync信号,当信号到来后才开始执行绘制任务。