关于UI卡顿:
简单的来说UI卡顿就是,微量级的anr。
复杂的来说:
原理:
60fps ->16ms
每秒60帧就能让人看起来不卡顿,也就是说程序的操作必须在16ms内加载完毕。
导致卡顿的原因就是,程序页面太过复杂,而在这16ms内没有渲染完毕。
在Android中造成卡顿的原因:
Android系统每隔16ms会发出信号,就会触发UI渲染,每次渲染成功就会让UI流畅。(CPU,GPU这段时间内执行完所有操作)
1.ListView或RecycleView 的itemlayout过于复杂
2.动画同一时间执行的太多,导致cpu,gpu负载过重。
3.频繁GC操作导致卡顿,Dalvik在每次GC时,会将所有的线程暂停,GC完后则才开始。
4.人为的在主线程中操作轻微的耗时操作。(耗时就是anr)
5.布局layout过于复杂(background绝对不要重叠)
6.view过度绘制
7.View频繁出发measure,layout,累计耗时过多及整个View频繁的重新渲染。
8.冗余资源以及逻辑导致加载和执行慢
overdraw(过度绘制)同一个像素绘制多次,各个像素有大量重叠的部分。
多层次的ui结构
系统调试:
开启Android过度绘制调试
1.浅蓝色代表屏幕上一个像素只被绘制了一次。
2.薄荷绿代表屏幕上一个像素被绘制了两次。
3.浅粉色代表屏幕上一个像素被绘制了三次。
4.红色代表屏幕上一个像素被绘制了四次及以上。
例子:主layout有background,子view也有background,就会进行过度绘制,减少重叠的部分绘制,就能降低UI卡顿
GPU呈现模式分析:
绿色为基准线,意思是16ms,如果超过这个线就说明丢帧了。
如何优化:
1、使用merge标签
使用merge来减少没用的layout嵌套
2、ViewStub标签
当系统碰到ViewStub标签的时候是不进行任何处理(measure、layout等),比设置View隐藏、不可见更高效。当我们真正需要显示某一个布局的时候才去渲染。
3、include标签
重用代码减少冗余
4、尽量不要嵌套布局
5、尽量减少layout中不必要的背景设置,有图片的话一定要压缩
比如说根节点设置背景色,使得RecycleView中有间隔分割线。图片过大会导致大量的内存消耗。
6、大面积的不可见区域尽量不要绘制,有需要的话建议动态绘制。
7、不要过于复杂的布局
8、用gone替代invisible
9、固定长和宽替代weight减少运算
layout_weight会使LinearLayout measure2次
10、item存在复杂的嵌套时可以采用自定义view来减少嵌套,减少measure测量和layout摆放的次数