前言
在讲 Canvas 绘图之前,我们先来简单介绍下硬件加速,因为开启硬件加速后,Canvas的某些方法会失效,这时需要关闭硬件加速才能看到效果。
从 Android 3.0(API 级别 11)开始,Android 2D 渲染管道支持硬件加速,也就是说,在 View 的画布上执行的所有绘制操作都会使用 GPU。启用硬件加速需要更多资源,因此应用会占用更多内存。如果最低 版本为 14 及更高级别,则硬件加速默认处于启用状态。
Q:什么是硬件加速?
A:所谓硬件加速,指的是把某些计算工作交给专门的硬件来做,而不是和普通的计算工作一样交给 CPU 来处理。这样不仅减轻了 CPU 的压力,而且由于有了「专人」的处理,这份计算工作的速度也被加快了。这就是「硬件加速」。
而对于 Android 来说,硬件加速有它专属的意思:在 Android 里,硬件加速专指把 View 中绘制的计算工作交给 GPU 来处理。进一步地再明确一下,这个「绘制的计算工作」指的就是把绘制方法中的那些 Canvas.drawXxx() 变成实际的像素这件事。
怎么就加速了?
-
用了 GPU(自身的设计本来就对于很多常见类型内容的计算,例如简单的圆形、简单的方形等具有优势),绘制变快了
-
绘制机制的改变,导致界面内容改变时的刷新效率极大提高
如果想了解更多关于硬件加速的底层原理,可以查看这篇文章理解Android硬件加速原理的小白文。
硬件加速开关
- Application
1 | |
- Activity
1 | |
- Window
1 | |
- View
1 | |
如何判断当前是否开启硬件加速?
1 | |
由于通常情况下,canvas是绘制的载体,所以应该通过canvas进行判断
硬件加速使用限制
硬件加速虽好,但开启硬件加速后,绘制Canvas的某些方法失效或无效,在使用时需要注意这些方法:
-
Canvas
方法 开始支持API版本 drawBitmapMesh()(颜色数组) 18 drawPicture() 23 drawPosText() 16 drawTextOnPath() 16 drawVertices() ✗ setDrawFilter() 16 clipPath() 18 clipRegion() 18 clipRect(Region.Op.XOR) 18 clipRect(Region.Op.Difference) 18 clipRect(Region.Op.ReverseDifference) 18 clipRect()(通过旋转/透视) 18 -
Paint
方法 开始支持API版本 setAntiAlias()(适用于文本)(颜色数组) 18 setAntiAlias()(适用于线条) 16 setFilterBitmap() 17 setLinearText() ✗ setMaskFilter() ✗ setPathEffect()(适用于线条) 28 setShadowLayer()(除文本之外) 28 setStrokeCap()(适用于线条) 18 setStrokeCap()(适用于点) 19 setSubpixelText() 28 -
Xfermode
方法 开始支持API版本 PorterDuff.Mode.DARKEN(帧缓冲区) 28 PorterDuff.Mode.LIGHTEN(帧缓冲区) 28 PorterDuff.Mode.OVERLAY(帧缓冲区) 28 -
Shader
方法 开始支持API版本 ComposeShader 内的 ComposeShader 28 ComposeShader 内相同类型的着色器 26 ComposeShader 上的本地矩阵 18 -
Scale
方法 开始支持API版本 drawText() 18 drawPosText() 28 drawTextOnPath() 28 简单的形状 17 复杂的形状 28 drawPath() 28 阴影层 28 简单形状,是指使用
Paint发出的drawRect()、drawCircle()、drawOval()、drawRoundRect()和drawArc()(其中 useCenter=false)命令,该Paint不包含PathEffect,也不包含非默认联接(通过setStrokeJoin()/setStrokeMiter())。这些绘制命令的其他实例都属于上表中的“复杂”形状。