Android性能优化系列——Understanding Overdraw

过度绘制(Overdraw)是指在一帧的时间内像素被绘制了多次;
理论上一个像素每次只绘制一次是最优的,但是由于层叠的布局导致一些像素会被多次绘制,而每次绘制都会对应到CPU的一组绘图命令和GPU的一些操作,所以对重叠不可见元素的重复绘制会产生额外的计算,需要尽量减少Overdraw的发生。

技术分享

Android系统提供了测量Overdraw的选项,在开发者选项-调试GPU过度绘制(Show GPU Overdraw),打开选项就可以看到当前页面Overdraw的状态。

技术分享

根据overdraw的次数会显示不同的颜色来区分

  • transparent = no overdraw
  • blue = 1 layer
  • green = 2 layers
  • light-red = 3 layers
  • dark red = you’re doing it wrong

优化方法

总的原则就是:尽量避免重叠不可见元素的绘制

  1. 去除不需要的背景资源

    • 在theme中添加 android:windowbackground="null"
    • 在Activity中设置getWindow().setBackgroundDrawable(null)
      这个方法要在setContentView()之后,因为getWindow().setBackground(Drawable)会讲这里的Drawable设置到DecorView的background,默认是0xff000000,而setContentView才会第一次初始化phoneWindow的DecorView;
  2. 分段设置背景
    有时候为了方便会先给Layout设置一个整体的背景,再给子View设置背景,这里也会造成重叠,如果子View宽度mach_parent,可以看到完全覆盖了Layout的一部分,这里就可以通过分别设置背景来减少重绘。

  3. View onDraw()方法
    自定义View绘制时避免重叠部分的绘制,可以使用

canvas.clipRect(); // 裁剪canvas
canvas.quickReject(); // 判断矩形区域是否相交

其他绘制优化建议

  1. 在onDraw函数里尽量避免分配内存、创建对象,会导致频繁的垃圾回收降低性能;
    在初始化、或者动画间隙做这些事情
  2. 减少invalidate的调用
  3. 尽可能保持layout的扁平化,尽可能少调用requestLayout(),requestLayout会导致系统遍历整个View树重新去measure和layout,如果layout嵌套复杂,这里也会产生性能问题
  4. 如果布局复杂,可以考虑自定义ViewGroup来特殊处理

Reference

Android Performance Patterns: Understanding Overdraw
Android Performance Patterns: Invalidations, Layouts, and Performance

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。