SurfaceView小结

来源:互联网 发布:oracle单条数据被锁 编辑:程序博客网 时间:2024/04/30 03:39

1.前言
(1)View是android的一个超类,每个View都有一个用于绘图的canvas,这个画布可以任意扩展;
(2)但是要绘制复杂的图形或对程序执行效率比较高时,View就无法满足需求;
(3)View是widget框架下的一个直接拖拉的控件;显示视图,内置画布,提供图形绘制函数,触屏时间、按键事件函数等,必须在UI主线程内更新画面,速度较慢。
(4)surfaceview实现双缓冲,可以直接访问canvas,执行效率更高;

2.基本介绍
(1)视图View的继承类,更适合2D游戏开发,内嵌一个专门用于绘图的Surface,采用双缓冲机制,绘制效率更高;可以控制Surface的格式及尺寸;Surface控制surface的绘制位置;
(2)surface是纵深Z-ordered的,表明它总在自己所在窗口的后面;
(3)surfaceView提供了一个可见区域,只有在这个可见区域内的surface部分内容才可见,可见区域外的surface是不可见的;
(4)Surface的排版显示受层级关系影响,其兄弟视图节点在顶端显示;所以兄弟视图会遮挡;此特性可以用于放置遮盖物(overlays),如文本和按钮控件;
(5)如果surface上有透明控件,它的每次变化都会引起框架重新计算它和顶层控件的透明效果,这会影响性能;

3.用法
(1)通过SurfaceHolder接口访问Surface,getHolder()可以得到这个接口;
(2)surfaceview变得可见时,surface被创建(surfaceCreated(SurfaceHolder)),surface隐藏时,surface被surface销毁(surfaceDestroyed(SurfaceHolder));
(3)surfaceview的核心在于提供两个线程:UI线程和渲染线程;
1)所有SurfaceView和SurfaceHolder.Callback的方法都应该在UI线程里调用;一般而言就是应用程序主线程;
2)渲染线程所要访问的各种变量应该作同步处理;

  1. SurfaceView类
    Public Constructors(构造函数)
    SurfaceView(Context context)
    SurfaceView(Context context, AttributeSet attrs)
    SurfaceView(Context context, AttributeSet attrs, int defStyle)

Public Methods(公共函数)
void draw(Canvas canvas)
Manually render this view (and all of its children) to the given Canvas.

boolean gatherTransparentRegion(Region region)
This is used by the RootView to perform an optimization when the view hierarchy contains one or several SurfaceView.

SurfaceHolder getHolder()
Return the SurfaceHolder providing access and control over this SurfaceView’s underlying surface.

void setSecure(boolean isSecure)
Control whether the surface view’s content should be treated as secure, preventing it from appearing in screenshots or from being viewed on non-secure displays.

void setVisibility(int visibility)
Set the enabled state of this view.

void setZOrderMediaOverlay(boolean isMediaOverlay)
Control whether the surface view’s surface is placed on top of another regular surface view in the window (but still behind the window itself).

void setZOrderOnTop(boolean onTop)
Control whether the surface view’s surface is placed on top of its window.

5.surfaceview类和View类的区别
(1)本质区别在于,surfaceview是在一个单独的线程中绘图,而view则是在UI主线程中更新画面;
在UI的主线程中更新画面,可能会引发问题,比如更新画面时间过长,那么UI线程会被阻塞,将无法响应按键,触摸等消息;
使用surfaceview由于在新启动的线程中更新画面不会阻塞UI主线程,但是这会有另外一个问题,就是事件同步;比如你触屏了一下,需要surfaceview中thread处理,一般需要有一个event queue的设计来保存touch event,这样比较复杂;
(2)View:必须在UI的主线程中更新画面,用于被动更新画面。
surfaceView:UI线程和子线程中都可以。在一个新启动的线程中重新绘制画面,主动更新画面。
(3)在游戏应用上,根据游戏的特点,一般分为两类:
1)被动更新画面的。比如棋类,这种用view就好。因为画面的跟新依赖于onTouch来更新,可以直接使用invalidate.因为这种情况下,这一次Touch和下一次Touch需要的时间比较长些,不会产生影响。
2)主动更新:比如一个人在一直跑动。这就需要一个单独的thread不停地重绘人的转台,避免阻塞mian UI Thread 。所以显然view 不适合,需要surfaceView来控制。

  1. 需要重写的方法:
    a. public void sufaceChanged(SurfaceHolder holder,int format,int width,int height){}//Surface的大小发生改变时调用
    b. public void surfaceCreated(SurfaceHolder holder){}//Surface创建时激发,一般在这里调用画面的线程。
    c. public void surfaceDestroyed(SurfaceHolder holder){}//销毁时激发,一般在这里将画面的线程停止、释放。
    d. public void addCallback{};//给SurfaceView添加一个回调函数。
    e. public void lockCanvas{};//锁定画布。绘图之前必须锁定画布才能够得到画布对象。
    f. public void unlockCanvasAndPost{};//开始绘制时锁定了画布,绘制完成后解锁画布。
    g. public void removeCallback:从SurfaceView中移除回调函数。
    SurfaceView不同View之处在于,SurfaceView不需要通过线程来更新视图,但是再绘制前需要使用locakCanvas锁定画布,并且得到画布,然后再画布上绘制你需要的图像。绘制完成后需要使用lockCanvasAndPost方法来解锁画布。于是才能显示在屏幕上。事件的处理规则和View是一样的。
    整个实现过程:
    继承SurfaceView并实现SurfaceHolder.Callback接口——>SurfaceView.getHolder()获得SurfaceHolder对象—–>SurfaceHolder.addCallback(callback)添加回调函数—>
    surfaceHolder.lockCanvas()获得Canvas对象并锁定画布—>Canvas绘画—>SurfaceHolder.unlockCanvasAndPost(Canvas canvas)结束锁定画图,并提交改变,将图形显示。
0 0
原创粉丝点击