Overdraw(过度绘制)描述的是屏幕上的某个像素在同一帧的时间内被绘制了多次。在多层次的UI结构里面,如果不可见的UI也在做绘制的操作,这就会导致某些像素区域被绘制了多次。这就浪费大量的CPU以及GPU资源。比如说,一个TextView后有背景,那么显示文本的像素至少绘了两次,一次是背景,一次是文本,这就好比你在墙壁上先后涂了两次颜色涂料,甚至后期又贴了墙纸,前面的工作其实就没有什么意义了,而且是非必要的。
当设计上追求更华丽的视觉效果的时候,我们就容易陷入采用越来越多的层叠组件来实现这种视觉效果的怪圈。这很容易导致大量的性能问题,为了获得最佳的性能,我们必须尽量减少Overdraw的情况发生。
幸运的是,我们可以通过手机设置里面的开发者选项,打开Show GPU Overdraw的选项,可以观察UI上的Overdraw情况。
蓝色,淡绿,淡红,深红代表了4种不同程度的Overdraw情况,我们的目标就是尽量减少红色Overdraw,看到更多的蓝色区域。
Overdraw有时候是因为你的UI布局存在大量重叠的部分,还有的时候是因为非必须的重叠背景。例如某个Activity有一个背景,然后里面的Layout又有自己的背景,同时子View又分别有自己的背景。仅仅是通过移除非必须的背景图片,这就能够减少大量的红色Overdraw区域,增加蓝色区域的占比。这一措施能够显著提升程序性能。
上面对过度绘制进行了基本的介绍,那么过度绘制的产生场景有哪些呢,一般冗余的背景、嵌套的Layout,一般通过如下方案可以解决过度绘制问题:
(1)如果有一个layout中嵌套多个其他view,且view的背景色和被包含的layout的背景色一致,则保持当前layout的背景色不变,将嵌套的其他view的背景色全部改成透明色,既保证该层不会绘制,也同时保证不会出现黑色背景(2)在牵涉到嵌套时,布局设计应该注意嵌套的布局的背景色是否和被嵌套的布局背景色一致,如果一致可以考虑去除相同的背景色,减少绘制;(3)在布局中,如果存在多个线性布局重叠时,可以考虑只针对最上层的布局设置背景色,而不需要每一个布局(例如LinearLayout)都设置背景色,过多的相同的背景色会导致过度绘制;(4)在设计到activity类中,如果牵涉到的布局存在背景色,可以考虑消除窗口的背景色,减少1X的绘制。(5)ViewStub的使用,为了解决重复定义相同布局的问题(6)merge等标签的使用,减少在include布局文件时的层级。