先说说自定义 View 绘图机制的缺陷:
1. View 缺乏双缓冲机制;
2. 当程序需要更新 View 上的图片时,程序必须重绘 View 上显示的整张图片;
3. 新线程无法直接更新 View 组件。
由于 View 存在上述的缺陷,所以通过自定义 View 来实现绘图,尤其是游戏中的绘图时性能并不好。Android 提供了一个 SurfaceView 来代替 View ,在实现游戏绘图方面,SurfaceView 比 View 更加出色。
在 Android UI 开发中一般遵循这样的规定:不要在主线程之外的线程中修改任何与 View 相关的属性。但是 SurfaceView 和 TextureView 这两个类则不遵循这个规定,它们专门设计用来在后台线程中执行绘制命令,并将绘制内容展现在屏幕上。
SurfaceView 一般会与 SurfaceHolder 结合使用。SurfaceView 非常独特,与传统 View 的原理有很大差异。当实例化一个 SurfaceView 时,实际上会在 View 的位置创建里一个窗口,所以实际上会有两层窗口,第二层就是 SurfaceHolder 该层位于当前窗口的下方,该层才是真正的视图层。然后 View 控件会在顶层窗口简单地“打一个洞”来透明地显示下方窗口的内容。SurfaceView 还是一种非常静态的视图,无法对动画或任何形式的变换做出很好的响应。
调用 SurfaceView 的 getHolder() 方法即可获取 SurfaceView 关联的 SurfaceHolder。SurfaceHolder 提供了如下方法来获取 Canvas 对象。
------> Canvas lockCanvas():锁定整个 SurfaceView 对象,获取该 SurfaceView 上的 Cnavas。
------> Canvas lockCanvas(Rect dirty):锁定 SurfaceView 上 Rect 划分的区域,获取该 SurfaceView 上的 Canvas。
上面的第二个方法获取指定的 Canvas 时,SurfaceView 将只对 Rect 所“圈”出来的区域进行绘图,通过这种方式可以提高画面的更新速度。
当通过 lockCanvas() 获取指定 SurfaceView 上的 Canvas 之后,接下来程序就可以调用 Canvas 进行绘图了, Canvas 绘图完成后通过如下方法