硬件加速默认开启,layerType默认为none
在硬件加速关闭的时候,Canvas 绘制的工作方式是:把要绘制的内容写进一个 Bitmap,然后在之后的渲染过程中,这个 Bitmap 的像素内容被直接用于渲染到屏幕。这种绘制方式的主要计算工作在于把绘制操作转换为像素的过程(例如由一句 Canvas.drawCircle() 来获得一个具体的圆的像素信息),这个过程的计算是由 CPU 来完成的。
而在硬件加速开启时,Canvas 的工作方式改变了:它只是把绘制的内容转换为 GPU 的操作保存了下来,然后就把它交给 GPU,最终由 GPU 来完成实际的显示工作。
如果您的目标 API 级别为 14 及更高级别,则硬件加速默认处于启用状态,但也可以明确启用该功能。如果您的应用仅使用标准视图和 Drawable,则全局启用硬件加速不会造成任何不良绘制效果。
setLayerType() 这个方法,它的作用其实就是名字里的意思:设置 View Layer 的类型。
所谓 View Layer,又称为离屏缓冲(Off-screen Buffer),它的作用是单独启用一块地方来绘制这个 View ,而不是使用软件绘制的 Bitmap 或者通过硬件加速的 GPU。
这块「地方」可能是一块单独的 Bitmap,也可能是一块 OpenGL 的纹理(texture,OpenGL 的纹理可以简单理解为图像的意思),具体取决于硬件加速是否开启。采用什么来绘制 View 不是关键,关键在于当设置了 View Layer 的时候,它的绘制会被缓存下来,而且缓存的是最终的绘制结果,而不是像硬件加速那样只是把 GPU 的操作保存下来再交给 GPU 去计算。
通过这样更进一步的缓存方式,View 的重绘效率进一步提高了:只要绘制的内容没有变,那么不论是 CPU 绘制还是 GPU 绘制,它们都不用重新计算,而只要只用之前缓存的绘制结果就可以了。
错误认知:之前以为通过这个方法开启了硬件加速,实则不然,这个方法只是开启了layer缓存。
硬件加速可以使用 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.setLayerType(View.LAYER_TYPE_HARDWARE, null)
ObjectAnimator.ofFloat(view, "rotationY", 180f).apply {
addListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
view.setLayerType(View.LAYER_TYPE_NONE, null)
}
})
start()
}
或者缩写为:
view.animate()
.rotationY(90)
.withLayer(); // withLayer() 可以自动完成上面这段代码的复杂操作