2024年3月12日发(作者:)
Android之SurfaceView详解
展开全文
SurfaceView介绍
通常情况程序的View和用户响应都是在同一个线程中处理的,这也是为什么处理长
时间事件(例如访问网络)需要放到另外的线程中去(防止阻塞当前UI线程的操作和绘
制)。但是在其他线程中却不能修改UI元素,例如用后台线程更新自定义View(调用
View的在自定义View中的onDraw函数)是不允许的。 如果需要在另外的线程绘制界
面、需要迅速的更新界面或则渲染UI界面需要较长的时间,这种情况就要使用
SurfaceView了。
SurfaceView中包含一个Surface对象,而Surface是可以在后台线程中绘制的。
Surface属于 OPhone底层显示系统。SurfaceView的性质决定了其比较适合一些场景:
需要界面迅速更新、对帧率要求较高的情况。使用SurfaceView需要注意以下几点情况:
SurfaceView和ck函数都从当前SurfaceView窗口线程中调用
(一般而言就是程序的主线程)。有关资源状态要注意和绘制线程之间的同步。 在绘制
线程中必须先合法的获取Surface才能开始绘制内容,在
和eCreated()
eDestroyed()之间的状态为合法的,另外在Surface类型
为SURFACE_TYPE_PUSH_BUFFERS时候是不合法的。 额外的绘制线程会消耗系统的资
源,在使用SurfaceView的时候要注意这点。
使用SurfaceView 只要继承SurfaceView类并实现ck接口就
可以实现一个自定义的SurfaceView了,ck在底层的Surface状
态发生变化的时候通知View,ck具有如下的接口:
surfaceCreated(SurfaceHolder holder):当Surface第一次创建后会立即调用该函
数。程序可以在该函数中做些和绘制界面相关的初始化工作,一般情况下都是在另外的线
程来绘制界面,所以不要在这个函数中绘制Surface。
surfaceChanged(SurfaceHolder holder, int format, int width,int height):当
Surface的状态(大小和格式)发生变化的时候会调用该函数,在surfaceCreated调用
后该函数至少会被调用一次。
surfaceDestroyed(SurfaceHolder holder):当Surface被摧毁前会调用该函数,该
函数被调用后就不能继续使用Surface了,一般在该函数中来清理使用的资源。
通过SurfaceView的getHolder()函数可以获取SurfaceHolder对象,Surface 就在
SurfaceHolder对象内。虽然Surface保存了当前窗口的像素数据,但是在使用过程中是
不直接和Surface打交道的,由SurfaceHolder的Canvas lockCanvas()或则Canvas
lockCanvas(Rect dirty)函数来获取Canvas对象,通过在Canvas上绘制内容来修改
Surface中的数据。如果Surface不可编辑或则尚未创建调用该函数会返回null,在
unlockCanvas() 和 lockCanvas()中Surface的内容是不缓存的,所以需要完全重绘
Surface的内容,为了提高效率只重绘变化的部分则可以调用lockCanvas(Rect dirty)函
数来指定一个dirty区域,这样该区域外的内容会缓存起来。在调用lockCanvas函数获
取Canvas后,SurfaceView会获取Surface的一个同步锁直到调用
unlockCanvasAndPost(Canvas canvas)函数才释放该锁,这里的同步机制保证在
Surface绘制过程中不会被改变(被摧毁、修改)。当在Canvas中绘制完成后,调用函


发布评论