1.SurfaceView简介
Android的绘图机制是由UI线程在屏幕上绘图,一般情况下不允许其他线程直接做绘图操作。这个机制在处理简单页面时没什么问题,因为普通页面不会频繁且大面积地绘图,但是该机制在处理复杂多变的页面时会产生问题,比如时刻变化着的游戏界面、拍照或录像时不断变换着的预览界面就会导致UI线程资源堵塞,即界面卡死的状况。
表面视图SurfaceView是Android用来解决子线程绘图的特殊视图,拥有独立的绘图表面,即不与其宿主页面共享同一个绘图表面。由于拥有独立的绘图表面,因此表面视图的界面能够在一个独立线程中进行绘制,这个子线程为渲染线程。因为渲染线程不占用主线程资源,所以一方面可以实现复杂而高效的UI刷新,另一方面即时响应用户的输入事件。由于表面视图具备以上特性,因此可用于拍照和录像的预览界面,也可用于游戏的实时界面。
2.SurfaceHolder简介及相关API
因为表面视图不在UI主线程绘图,无论是onDraw方法还是dispatchDraw方法都没有进行绘图操作,所以表面视图必然要通过其他途径绘图,这个途径便是内部类表面持有者SurfaceHolder外部调用SurfaceVIew对象的getHolder方法获取SurfaceHolder对象,然后进行预览界面的相关绘图操作。
常用API如下:
- lockCanvas:锁定并获取绘图表面的画布。
- unlockCanvasAndPost:解锁并刷新绘图表面的画布。
- addCallback:添加绘图表面的回调接口SurfaceHolder.Callback。回调接口有以下三个方法。
surfaceCreated | 在绘图表面创建后触发,可在此打开相机。 |
surfaceChanged | 在绘图表面变更后触发。 |
surfaceDestroyed | 在绘图表面销毁后触发。 |
- removeCallback:移除绘图表面的回调接口。
- isCreating:判断绘图表面是否有效。如果在别处操作SurfaceView,就要判断当前绘图表面是否有效。
- getSurface:获取绘图表面的对象,即预览界面。
- setFixedSize:设置预览界面的尺寸。
- setFormat:设置绘图表面的格式。绘图格式的取值如下
PixelFormat类的绘图格式类型 | 说明 |
TRANSPAREN | 透明 |
TRANSLUCENT | 半透明 |
OPAQUE | 不透明 |
3.表面视图与普通视图的区别
- 表面视图允许开启多个线程同时进行绘图操作,而普通视图只有一个UI线程可以绘图。
- 表面视图不会自动清空上次的绘图结果,即绘图操作是增量进行的,而普通视图在每次绘图前都会清空上次的绘图结果。