Android性能优化系列——卡顿优化
卡顿,就是用户体感界面不流畅。我们知道手机的屏幕画面是按照一定频率来刷新的,理论上讲,24 帧的画面更新就能让人眼感觉是连贯的。但是实际上,这个只是针对普通的视频而言。对于一些强交互或者较为敏感的场景来说,比如游戏,起码需要 60 帧,30 帧的游戏会让人感觉不适;如果实现不卡顿,则需要在 16ms 内做完所有的操作才不会造成卡顿。
卡顿一般可能由以下条件造成的:
- UI卡顿
- 内存泄漏,内存抖动,内存溢出
- IO阻塞,IO操作,网络操作
- 图片,数据处理不当等等
1.UI优化
Android中通常把布局文件写在XML中,Android需要把XML布局文件转换成GPU能够识别并绘制的对象,CPU负责把UI组件计算成Polygons,Texture纹理,然后交给GPU进行栅格化渲染,最后硬件将信息绘制到屏幕上。
为了使APP流畅,我们需要在每一帧16ms内完成所有的CPU与GPU的计算、绘制、渲染等操作,也就是帧率为60fps,为什么要帧率为60fps呢?因为人眼与大脑之间的协作无法感知超过60fps的画面更新,开发APP的性能目标就是保持60fps,这意味着每一帧只有16ms(1000/60)的时间来处理所有任务。
但是我们遇到很多帧率小于刷新频率,这种情况下,某些帧显示的画面内容就会与上一帧的相同,帧率如果从高于60fps突然掉落到低于60fps就会发生卡顿不顺滑的情况。这也是用户感受卡顿的原因所在。
我们一般都比较了解 view 渲染的三大流程,但是 view 的渲染远不止于此:
此处以一个通用的硬件加速流程来表征
- Vsync 调度:很多同学的一个认知误区在于认为 vsync 是每 16ms 都会有的,但是其实 vsync 是需要调度的,没有调度就不会有回调;
- 消息调度:主要是 doframe 的消息调度,如果消息被阻塞,会直接造成卡顿;
- input 处理:触摸事件的处理;
- 动画处理:animator 动画执行和渲染;
- view 处理:主要是 view 相关的遍历和三大流程;
- measure、layout、draw:view 三大流程的执行;
- DisplayList 更新:view 硬件加速后的 draw op;
- OpenGL 指令转换:绘制指令转换为 OpenGL 指令;
- 指令 buffer 交换:OpenGL 的指令交换到 GPU 内部执行;
- GPU 处理:GPU 对数据的处理过程;
- layer 合成:surface buffer 合成屏幕显示 buffer 的流程;
- 光栅化:将矢量图转换为位图;
- Display:显示控制;
- buffer 切换:切换屏幕显示的帧 buffer;
所以UI渲染机制中的任何流转过程发生异常,均会造成卡顿。
在View第一次被渲染时,DisplayList就会被构建,View显示到屏幕上时,会执行GPU的指令来进行渲染,如果后续还有移动位置等操作时再次渲染这个View时,仅仅额外执行一次渲染指令就可以了。但是如果修改了View中某些可见组件,DisplayList就无法再次使用,需要重新构建再渲染。任何View中的绘制内容发生变化时,都会执行DisplayList构建和渲染,更新到屏幕等一系列操作,这个流程表现的性能取决于View的复杂程度,View的状态变化以及View渲染管道的执行力。所以我们需要尽量减少过渡绘制(OverDraw)。
综上,针对页面布局的性能,层级,测量绘制时间进行优化,所以布局优化就是减少层级,减少OverDraw,性能耗费少,越简单越好。
而我们平时敲的代码主要就涉及上面的3,4,5,6,我们可以在上面的代码进行优化,优化的方向可以看我另一篇文章:
Android性能优化系列——UI优化-CSDN博客
2.内存优化
下面是内存泄漏的常见原因和解决方案,具体可以去看以下文章
Android性能优化系列——内存优化-CSDN博客