UI卡顿原理:

“60fps(Frames Per Second每秒传输帧数) ----> 16ms”

针对上面标红的数字,下面具体说明一下:最主要的根源在于渲染性,Android会每隔16ms会发出信号,触发对UI进行渲染,如果每一次都渲染成功,则就达到流畅画面所需要的60fps,也就是每秒60针,为了能够达到60fps,程序的大多数操作必须在16ms内完成,也就是1000ms/60=16ms,为什么要把标准设定在60fps呢?人脑对于画面的连贯性是有一定的限制的,而android系统把这种流畅的帧率规定在60fps,也就是每秒实现的帧数,算换过来就是16ms一帧,也就是一秒60帧,所以说为了保证不出现丢失帧数,我们一定要在16ms内处理这次的CPU和GPU的计算和渲染操作,另外还需知道当Dalvik虚拟机达到GC的时候所有线程都会暂停,所GC完之后线程才能够继续执行,也就是说如果在16ms进行界面渲染的时候正好遇到大量的GC操作就会导致渲染时间不够,从页导致卡顿问题。

overdraw(过度绘制):出现的原因是UI布局中有大量重叠的部份,比如Activity中有一个背景,而View也有自己的背景,类似于这种就会容易造成过度绘制,这个可以从开发者选项中进行观测,减少红色部份,尽量只有绿色部份。

UI卡顿原因分析:


  • 人为在UI线程中做轻微耗时操作,导致UI线程卡顿。
  • 布局Layout过于复杂,无法在16ms内完成渲染。
  •  同一时间动画执行的次数过多,导致CPU或GPU负载过重。
  • View过度绘制,导致某些像素在同一帧时间内被绘制多次,从而使CPU或GPU负载过重。
  • View频繁的触发measure、layout,导致measure、layout累计耗时过多及整个View频繁的重新渲染。
  • 内存频繁触发GC过多,导致暂时阻塞渲染操作。
  • 冗余资源及逻辑等导致加载和执行缓慢,良好的代码习惯也能提高UI的性能。
  • ANR。

UI卡顿总结:


  • 布局优化:用merge、viewStub标题;尽量不存在冗余嵌套和过于复杂的布局;如果布局是通用的可以用include来导入;尽量使用GONE替换INVIsible,因为invisible界面依然会绘制;尽量用weight替换长和宽;如果Item存在非常复杂的嵌套时可以考虑用自定义的View来改良来减少measure、layout的次数而提高性能。
  • 列表及Adapter优化:利用缓存及滑动监听,滑动时不去更新UI。
  • 背景和图片等内存分配优化。
  • 避免ANR。