android(二) SurfaceView

(一)常用类介绍

(1). View:显示视图,内置画布,提供图形绘制函数、触屏事件、按键事件函数等;必须在UI主线程内更新画面,被动更新画面,速度较慢。

(2). SurfaceView:基于view视图进行拓展的视图类,更适合2D游戏的开发;是view的子类,类似使用双缓机制,UI线程和子线程中都可

以更新画面。在一个新启动的线程中重新绘制画面,主动更新画面。

(3). GLSurfaceView:基于SurfaceView视图再次进行拓展的视图类,专用于3D游戏开发的视图;是SurfaceView的子类,openGL专用。


     UI的主线程中更新画面 可能会引发问题,比如你更新画面的时间过长,那么你的主UI线程会被你正在画的函数阻塞。那么将无法响应按键,

触屏等消息。当使用surfaceView 由于是在新的线程中更新画面所以不会阻塞你的UI主线程。但这也带来了另外一个问题,就是事件同步,涉

及到线程同步。所以基于以上,根据游戏特点,一般分成两类。 


  1 被动更新画面的。比如棋类,这种用view就好了。因为画面的更新是依赖于 onTouch 来更新,可以直接使用 invalidate。 因为这种情况下,

这一次Touch和下一次的Touch需要的时间比较长些,不会产生影响。 

  2 主动更新。比如一个人在一直跑动。这就需要一个单独的thread不停的重绘人的状态,避免阻塞main UI thread。所以显然view不合适,

需要surfaceView来控制。 

(二)SurfaceView用法

  首先继承SurfaceView并实现SurfaceHolder.Callback接口。因为使用SurfaceView 有一个原则,所有的绘图工作必须得在Surface 被创建之

后才能开始。可以被直接复制到显存从而显示出来,这使得显示速度会非常快,而在Surface 被销毁之前必须结束。所以Callback 中的surfaceCreated

和surfaceDestroyed 就成了绘图处理代码的边界。

需要重写的方法

 (1)public void surfaceChanged(SurfaceHolder holder,int format,int width,int height)------- //在surface的大小发生改变时激发

 (2)public void surfaceCreated(SurfaceHolder holder)-------//在创建时激发,一般在这里调用画图的线程。

 (3)public void surfaceDestroyed(SurfaceHolder holder)---------//销毁时激发,一般在这里将画图的线程停止、释放。

整个过程:

(1)继承SurfaceView并实现SurfaceHolder.Callback接口

(2)SurfaceView.getHolder()获得SurfaceHolder对象

(3)SurfaceHolder.addCallback(callback)添加回调函数

(4)SurfaceHolder.lockCanvas()获得Canvas对象并锁定画布

(5)Canvas绘画

(6)SurfaceHolder.unlockCanvasAndPost(Canvas canvas)结束锁定画图,并提交改变,将图形显示。

(三)关于SurfaceHolder

可以把它当成surface的控制器,用来操纵surface。处理它的Canvas上画的效果和动画,控制表面,大小,像素等。几个需要注意的方法:

(1)、abstract void addCallback(SurfaceHolder.Callback callback)---------// 给SurfaceView当前的持有者一个回调对象。

(2)、abstract Canvas lockCanvas()-----------// 锁定画布,一般在锁定后就可以通过其返回的画布对象Canvas,在其上面画图等操作了。

(3)、abstract Canvas lockCanvas(Rect dirty)--// 锁定画布的某个区域进行画图等..因为画完图后,会调用下面的unlockCanvasAndPost来改变显示内容。

(4)、abstract void unlockCanvasAndPost(Canvas canvas)-----------// 结束锁定画图,并提交改变。

原文地址:https://www.cnblogs.com/yuyutianxia/p/3294128.html