概述
Android 从一诞生到现在已经发布的 7.0 版本,卡顿和不流畅问题却一直被人们所诟病。客观地来讲,Android 的流畅性确实一直不给力,哪怕是某些大厂的 App ,也都不同程度地存在卡顿问题。从开发角度来说,每个开发者都应该关注下性能优化,在平时的开发工作中注意一些细节,尽可能地去优化应用。
在 Android 开发中,UI 可以说是每个 App 使用频率很高的,随着 UI 越来越多,布局的重复性、复杂度也会随之增长,UI 设计或者布局不慎,就会引起过度绘制或者造成 UI 卡顿的情况,这样使得 UI 性能的优化,显得至关重要,UI 的质量也是产品质量的一部分。
2015年初,Google 发布了关于 Android 性能优化典范的专题,一共16个短视频,每个3-5分钟,帮助开发者创建更快更优秀的 Android App。课程专题不仅仅介绍了 Android 系统中有关性能问题的底层工作原理,同时也介绍了如何通过工具来找出性能问题以及提升性能的建议。今天我们就其中之一 Android 渲染机制开始讲起。
Android渲染机制
渲染性能
大多数用户感知到的卡顿等性能问题的最主要根源都是因为渲染性能。从设计师的角度,他们希望 App 能够有更多的动画,图片等时尚元素来实现流畅的用 户体验。但是 Android 系统很有可能无法及时完成那些复杂的界面渲染操作。Android 系统每隔16ms发出 VSYNC 信号,触发对 UI 进行渲染, 如果每次渲染都成功,这样就能够达到流畅的画面所需要的60fps,为了能够实现60fps,这意味着程序的大多数操作都必须在16ms内完成。
<img src="http://upload-images.jianshu.io/upload_images/2153668-540bd95044067551.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" />
如果你的某个操作花费时间是24ms,系统在得到VSYNC信号的时候就无法进行正常渲染,这样就发生了丢帧现象。那么用户在32ms内看到的会是同一帧画面。
<img src="http://upload-images.jianshu.io/upload_images/2153668-64ce9db72b29bc61.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" />
用户容易在 UI 执行动画或者滑动 ListView 的时候感知到卡顿不流畅,是因为这里的操作相对复杂,容易发生丢帧的现象,从而感觉卡顿。有很多原 因可以导致丢帧,也许是因为你的 layout 太过复杂,无法在16ms内完成渲染,有可能是因为你的 UI 上有层叠太多的绘制单元,还有可能是因为动画执行的次数过多。这些都会导致CPU或者GPU负载过重。
渲染组件
对于上面提到的 CUP 和 GPU,就需要我们了解 Android 的渲染机制,Android 的渲染主要分为两个组件:
- CPU
- GPU
他们主要的工作是:
<img src="http://upload-images.jianshu.io/upload_images/2153668-127c14718ee29fca.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" />
渲染操作通常依赖于两个核心组件:CPU 与 GPU。CPU负责包括 Measure,Layout,Record,Execute 的计算操作,把 UI 组件计算成Polygons,Texture纹理,然后交给GPU进行栅格化渲染。。CPU 通常存在的问题的原因是存在非必需的视图组件,它不仅仅会带来重复的计算操作,而且还会占用额外的 GPU 资源;GPU 通常存在的问题的原因是存在过度绘制。
Activity 如何将复杂的UI转换成用户看得懂的图像并绘制到屏幕上?
这是由格栅化操作完成的,所谓的栅格化就是绘制那些 Button,Shape,Path,String,Bitmap 等组件最基础的操作。它把那些组件拆分到不同的像素上进行显示,说的俗气一点,就是解决那些复杂的 XML 布局文件和标记语言,使之转化成用户能看懂的图像,但是这不是直接转换的,XML 布局文件需要在 CPU 中首先转换为多边形或者纹理,然后再传递给 GPU 进行栅格化。
说完了概念,继续分析上图,如何对 CPU 和 GPU 进行优化呢?
- 通过Hierarchy Viewer去检测渲染效率,去除不必要的嵌套;
- 通过Show GPU Overdraw去检测Overdraw,最终可以通过移除不必要的背景以及使用canvas.clipRect解决大多数问题。
到这里,你可能对 UI 优化还是不太理解,毕竟概念是枯燥的,下面我们就深入研究优化。