在 Android 里,硬件加速专指把 View 中绘制的计算工作交给 GPU 来处理。
进一步地再明确一下,这个「绘制的计算工作」指的就是把绘制方法中的那些 Canvas.drawXXX()
变成实际的像素这件事。
在硬件加速关闭的时候,Canvas
绘制的工作方式是:
把要绘制的内容写进一个 Bitmap
,然后在之后的渲染过程中,这个 Bitmap
的像素内容被直接用于渲染到屏幕。
这种绘制方式的主要计算工作在于把绘制操作转换为像素的过程(例如由一句 Canvas.drawCircle()
来获得一个具体的圆的像素信息),这个过程的计算是由 CPU 来完成的。
在硬件加速开启时,Canvas
的工作方式改变了:
它只是把绘制的内容转换为 GPU 的操作保存了下来,然后就把它交给 GPU,最终由 GPU 来完成实际的显示工作。
硬件加速能让绘制变快的三个原因:
- 本来由 CPU 自己来做的事,分摊给了 GPU 一部分,自然可以提高效率;
- 相对于 CPU 来说,GPU 自身的设计本来就对于很多常见类型内容的计算(例如简单的圆形、简单的方形)具有优势;
- 由于绘制流程的不同,硬件加速在界面内容发生重绘的时候绘制流程可以得到优化,避免了一些重复操作,从而大幅提升绘制效率。
有些操作方法在硬件加速下失效需要关闭,关闭硬件加速的代码
view.setLayerType(LAYER_TYPE_SOFTWARE, null);
事实上,这个方法的本来作用并不是用来开关硬件加速的,只是当它的参数为 LAYER_TYPE_SOFTWARE
的时候,可以「顺便」把硬件加速关掉而已;并且除了这个方法之外,Android 并没有提供专门的 View 级别的硬件加速开关,所以它就「顺便」成了一个开关硬件加速的方法。
setLayerType()
这个方法的作用是设置 View Layer 的类型。所谓 View Layer,又称为离屏缓冲(Off-screen Buffer),它的作用是单独启用一块地方来绘制这个 View ,而不是使用软件绘制的 Bitmap 或者通过硬件加速的 GPU。
这个方法不适用于基于自定义属性绘制的动画。
总结:
硬件加速指的是使用 GPU 来完成绘制的计算工作,代替 CPU。它从工作分摊和绘制机制优化这两个角度提升了绘制的速度。
硬件加速可以使用 setLayerType()
来关闭硬件加速,但这个方法其实是用来设置 View Layer 的:
- 参数为
LAYER_TYPE_SOFTWARE
时,使用软件来绘制 View Layer,绘制到一个 Bitmap,并顺便关闭硬件加速; - 参数为
LAYER_TYPE_HARDWARE
时,使用 GPU 来绘制 View Layer,绘制到一个 OpenGL texture(如果硬件加速关闭,那么行为和VIEW_TYPE_SOFTWARE
一致); - 参数为
LAYER_TYPE_NONE
时,关闭 View Layer。
View Layer 可以加速无 invalidate()
时的刷新效率,但对于需要调用 invalidate()
的刷新无法加速。
View Layer 绘制所消耗的实际时间是比不使用 View Layer 时要高的,所以要慎重使用。