过度绘制(Overdraw)是指在屏幕上的同一个像素点,在单帧渲染(one single frame)的过程中被绘制了多次。这种现象会额外消耗 GPU 资源,当过度绘制情况严重时,可能导致应用界面掉帧或卡顿。
通过安卓系统的开发者选项可以直观地检测过度绘制。
设置 -> 开发者选项 -> 硬件加速渲染 -> 调试 GPU 过度绘制 -> 显示过度绘制区域优化目标:尽可能减少或消除红色区域,并将绿色区域作为优化的次要目标。
1. 移除不必要的背景
这是最常见也是最容易优化的场景。
View 被另一个不透明的 View 完全覆盖时,底层 View 的背景就应该被移除。Fragment 的根布局设置了背景色,同时其内部的 RecyclerView 也设置了不透明的背景色,此时 Fragment 根布局的背景就是多余的。Activity 的 Theme 中包含了默认的 windowBackground,如果你的布局也设置了全屏的背景,那么主题中的背景就可以移除。2. 减少视图层级
使用 <merge> 标签
include 布局时,帮助“压平”视图层级。如果一个自定义 View 的根布局可以被合并到其父布局中,使用 <merge> 可以有效减少一个层级。使用 ConstraintLayout
ConstraintLayout(约束布局)非常适合构建复杂的 UI,它能创建出非常扁平化的视图结构,从而有效避免使用传统 LinearLayout 或 RelativeLayout 时产生的多层嵌套。3. 使用 canvas.clipRect() 精确指定绘制区域
View 的 onDraw() 方法中。canvas.clipRect() 方法可以定义一个裁剪区域,只有在这个区域内的绘制操作才会被执行。对于那些被其他视图完全遮挡的部分,我们可以通过计算将其排除在绘制区域之外,从而避免不必要的绘制操作。