UI卡顿问题总结
UI卡顿的原理
60fps->16ms
android 每隔16ms,触发一次UI渲染。如果每次渲染成功,就可以达到流畅的效果。否则就是卡顿。
为什么是60fps,因为人眼对画面的捕捉是有一定限制性的,达到60fps即每秒60帧及以上人眼是分辨不出来的。
换算过来就是16ms内要完成一帧的渲染。
overdraw
过度绘制
意思是屏幕上的某个像素在同一帧的时间内被绘制了很多次。
经常出现在多层次的UI结构里。
在开发者选项里可以打开gpu绘制选项观察overdraw现象。
有蓝色,淡绿色,淡红,深红色,四种情况。
目标是减少红色,尽量出现蓝色。
UI卡顿的原因分析
-
人为的在UI线程中做轻微的耗时操作,导致UI线程卡顿
什么是轻微就是卡顿但还不会造成anr -
布局layout过于复杂,无法在16ms内完成渲染
尤其要注意背景重叠 -
同一时间动画执行的次数过多,导致CPU或者GPU负载过重
-
view的过度绘制,导致某些像素在痛一帧时间内被绘制多次,从而是CPU或者GPU负载过重
第二点是从布局上考虑,第四点是从代码上考虑 -
view频繁的触发measure、layout,导致measure、layout累计耗时过多及整个view频繁的重新渲染
-
内存频繁的GC过多,导致暂时阻塞渲染操作
比如内存抖动,导致在16ms内无法绘制完成,因为GC时需要暂停线程工作 -
冗余资源及逻辑导致加载和执行缓慢
启动的逻辑,异步任务的处理不当,导致UI的卡顿 -
ANR
主线程中做了耗时操作
UI卡顿总结
-
布局优化
使用include、merge、viewsub标签
尽量不使用冗余嵌套,以及过于复杂的布局,就是布局不要嵌套,如果是通用布局,通过include来导入
而且尽量使用gone来提到invisible,因为invisible也是会绘制影响性能。但是gone就不会绘制。
尽量使用weight来代替长和宽,来减少运算。
如果item存在非常复杂的嵌套时,可以考虑自定义view来取代,这样可以减少measure测量和layout布局的次数,从而提高app的UI性能 -
列表以及adapter优化
体现在listview上,尽量复用listview的adapter在getView中的方法。使用convertView不要重复获取实例,
列表在滑动的时候不要进行元素的更新。也就是说listview在滑动的时候,你去监听它的滑动事件,只有滑动到停止的时候再去加载图片加载数据。
在滑动的时候可以只显示图片的缩略图,或者数据的默认值 -
背景和图片等的内存优化
尽量减少布局当中不必要的背景设置
图片要进行压缩处理
还有就是对GC的处理上一定要注意,当图片在16ms内渲染的时候,所造成的一些频繁gc回收从而导致内存泄漏的问题。 -
避免anr
不要在UI线程中做耗时操作,可以通过android提供的异步线程类,AsyncTask,HandlerThread,IntentService等处理耗时操作。