概述
SurfaceView是Android中比较特殊的一类视图,它与普通的View最主要的区别是它和它的视图容器并不是在一个视图层。
为什么要使用SurfaceView
我们知道Android系统中是提供了View来进行绘图处理,然后可以通过invalidate方法通知系统去调用view.onDraw方法去对界面进行重绘,而Android系统是通过发出VSYNC信号来进行屏幕的重绘,可以看出View是主动刷新,而且这个刷新时间是16ms,如果在16ms中没有执行完需要的操作,用户就会看着卡顿,如果draw方法中需要处理的逻辑太多,或者是游戏界面,需要频繁刷新复杂的界面,这样就会阻塞主线程,从而造成画面上的卡顿。而SurfaceView,它的绘制是在另外的线程中,不会去阻塞主线程,另外它底层实现了双缓冲机制。
从网上摘录了一段对双缓冲机制的介绍
双缓冲技术是游戏开发中的一个重要的技术。当一个动画争先显示时,程序又在改变它,前面还没有显示完,程序又请求重新绘制,这样屏幕就会不停地闪烁。而双缓冲技术是把要处理的图片在内存中处理好之后,再将其显示在屏幕上。双缓冲主要是为了解决反复局部刷屏带来的闪烁。把要画的东西先画到一个内存区域里,然后整体的一次性画出来。
SurfaceView中的MVC框架
我们要了解SurfaceView,还必须要了解和它息息相关的其他两个组件:Surface和SurfaceHolder。Surface其实就视图数据,SurfaceHolder我们都知道是个接口,用来进行绘制。而SurfaceView是显示视图并且和用户交互的界面。而MVC(Model-View-Controller)框架,model是数据,也就是这里的Surface,View是用来显示的,也就是SurfaceView,而控制器,也就是这里SurfaceHolder。
分析源码
- Surface、SurfaceHolder、surfaceView
Surface
java.lang.Object
↳ android.view.Surface
// Handle onto a raw buffer that is being managed by the screen compositor
public class Surface implements Parcelable {
//code....
}
- 首先看一下这个Surface类,实现了Parcelable接口进行了序列化(可以在进程中传递该类对象)用来处理屏幕显示缓冲区的数据。
- 源码中的注释是:Handle onto a raw buffer that is being managed by the screen compositor 翻译一下就是 对由屏幕图像合成器管理的原始缓冲区进行处理,也就是用来获取原始缓冲区以及其中的内容,原始缓冲区(raw buffer)是用来保存当前窗口的像素数据,由此可知Surface就是Android用来绘图的地方,
- 既然需要绘图,那肯定需要画布,也就是在其内部定义了Canvas对象
private final Canvas mCanvas =