什么是过度绘制?

Overdraw(过度绘制)是屏幕上的某个像素在同一帧的时间内被绘制了多次。在多层次的UI结构里面, 如果不可见的UI也在做绘制的操作,这就会导致某些像素区域被绘制了多次,这就浪费大量的CPU以及GPU资源。

颜色标识: GPU过渡绘制从好到差:蓝-绿-淡红-红

蓝色: GPU过度绘制了 1倍。像素绘制了两次。大片的蓝色还是可以接受的(若整个窗口是蓝色的,可以摆脱一层)。
绿色: GPU过度绘制了 2倍。像素绘制了三次。中等大小的绿色区域是可以接受的但你应该尝试优化、减少它们。
淡红: GPU过度绘制了 3倍。像素绘制了四次,小范围可以接受。
深红: GPU过度绘制了 4倍。像素绘制了五次或者更多。这是错误的,要修复它们。
我们的目标就是尽量减少红色Overdraw,看到更多的蓝色区域。

过度绘制产生的原因?

冗余的背景

嵌套的layout

解决方法:

  • 移除Window默认的Background
  • 移除XML布局文件中非必需的Background
  • 按需求显示占位背景图片
  • 减少布局嵌套

过度绘制检测工具:

Show GPU Overdraw 过渡渲染检测工具

我们可以通过手机设置里面的开发者选项,打开Show GPU Overdraw的选项,可以观察UI上的Overdraw情况。蓝色,淡绿,淡红,深红代表了4种不同程度的Overdraw情况,颜色越深 过渡渲染越厉害。我们的目标就是尽量减少红色Overdraw,看到更多的蓝色区域。

HierarchyViewer

不合理的布局会使我们的应用程序UI性能变慢,HierarchyViewer能够可视化的角度直观地获得UI布局设计结构和各种属性的信息,帮助我们优化布局设计。HierarchyViewer是我们优化程序的工具之一,它是Android自带的非常有用的工具,可以帮助我们更好地检视和设计用户界面(UI),绝对是UI检视的利器。

lint

冗余资源及逻辑等也可能会导致加载和执行缓慢,所以我们就来看看Lint这个工具是如何发现优化这些问题的.在Android Studio 1.4版本中使用Lint最简单的办法就是将鼠标放在代码区点击右键->Analyze->Inspect Code–>界面选择你要检测的模块->点击确认开始检测

优化点:

功能越复杂,也越容易产生性能问题,所以常遇到布局复杂、过渡绘制多、Activity主要函数耗时、内容展示慢、界面重新布局(Layout)、GC次数多等问题

include

当不同的界面有相同的UI元素的时候我们可以使用include标签,不过引入的布局还可能会被嵌套在LinearLayout,RelativeLayout里面。所以引入merge标签。

merge

在引入布局文件里面,最外层可以用merge替代LinearLayout,RelativeLayout,这样把子UI元素直接衔接在include位置

viewstub

viewstub标签同include标签一样可以用来引入一个外部布局,不同的是,viewstub引入的布局默认不会扩张,即既不会占用显示也不会占用位置,从而在解析layout时节省cpu和内存。
viewstub常用来引入那些默认不会显示,只在特殊情况下显示的布局,如进度布局、网络失败显示的刷新布局、信息出错出现的提示布局等。

减少layout层级

(1) 首次不需要使用的节点设置为GONE或使用viewstub
(2) 使用RelativeLayout代替LinearLayout。(这里存在疑问,有时候1层的RelativeLayout会比3层嵌套的LinearLayout实现的性能更糟糕。)
另外RelativeLayout通常会对它们的子视图进行2次测量,子视图使用了layout_weight属性的LinearLayout也会对它的子视图进行2次测量;我们一般推荐使用RelativeLayout,然而我们视项目具体问题具体分析。

关于include,merge,viewstub的使用可以查看

布局设计建议:

  1. 布局设计在牵涉到嵌套时,应该注意嵌套的布局的背景色是否和被嵌套的布局背景色一致,如果一致可以考虑去除相同的背景色,减少绘制;
  2. 在布局中,如果存在多个线性布局重叠时,可以考虑只针对最上层的布局设置背景色,而不需要每一个布局(例如LinearLayout)都设置背景色,过多的相同的背景色会导致过度绘制;
  3. 在设计到activity类中,如果牵涉到的布局存在背景色,可以考虑消除窗口的背景色,减少1X的绘制。