Android中View,SurfaceView和GLSurfaceView绘图的区别

转载:https://zhidao.baidu.com/question/626501648785925724.html

    Android游戏开发中常用的三种视图是:View、SurfaceView和GLSurfaceView,区别如下:
    View:显示视图,内置画布,提供图形绘制函数、触屏事件、按键事件函数等;必须在UI主线程内更新画面,速度较慢,用于被动更新画面。
    SurfaceView:基于View视图进行拓展的视图类,更适合2D游戏的开发;是View的子类,类似使用双缓机制,在一个新启动的线程中重新绘制画面,主动更新画面,所以刷新界面速度比View快。
    GLSurfaceView:基于SurfaceView视图再次进行拓展的视图类,专用于3D游戏开发的视图;是SurfaceView的子类,OpenGL专用。

    UI的主线程中更新画面可能会引发问题,比如你更新画面的时间过长,那么你的主UI线程会被你正在画的函数阻塞。那么将无法响应按键,触屏等消息。当使用SurfaceView由于是在新的线程中更新画面所以不会阻塞你的UI主线程。但这也带来了另外一个问题,就是事件同步,涉及到线程同步。所以根据游戏特点,一般分成两类:
    1. 被动更新画面的。比如棋类,这种用View就好了。因为画面的更新是依赖于onTouch来更新,可以直接使用invalidate。 因为这种情况下,这一次Touch和下一次的Touch需要的时间比较长些,不会产生影响。
    2. 主动更新。比如一个人在一直跑动。这就需要一个单独的thread不停的重绘人的状态,避免阻塞main UI thread。所以显然View不合适,需要SurfaceView来控制。

    如果你的游戏不吃CPU,用View就比较好,符合标准Android操作方式,由系统决定刷新Surface的时机。但如果很不幸的,你做不到不让你的程序吃CPU,你就只好使用SurfaceView来强制刷新Surface了,不然系统的UI进程很可能抢不过你那些吃CPU的线程。当然其实不止这两种方法来刷新Surface的,这两种只是纯Java应用比较常见的方法。一般2D游戏开发使用SurfaceView足够,因为它也是google专们扩展用于2D游戏开发的画布。
    使用普通的游戏画布(Android中2D专用游戏画布)中进行绘制图片,然后在GLSurfaceView(Android中3D游戏专用画布)中渲染图片的对比中发现GLSurfaceView的效率高于SurfaceView的30倍;GLSurfaceView的效率主要是因为机器硬件的GPU加速,弊端在于适配能力差,因为很多机型中是没有GPU加速的。


Android提供了两个基本的类让我们使用OpenGL ES API来创建和操纵图形:GLSurfaceView和 GLSurfaceView.Renderer。因此我们首先需要了解这两个类。
    1.     GLSurfaceView:
    这是一个视图类,你可以调用OpenGL API在上面绘制图形和操纵物体,功能和SurfaceView相似。我们可以创建一个GLSurfaceView类的实例,并添加自己的渲染器。如果我们要自己实现一些触摸屏的操作,我们必须扩展这个类来实现触摸监听器。
    2.     GLSurfaceView.Renderer
    这个接口定义了在一个OpenGL的GLSurfaceView中绘制图形所需要的方法。我们必须在一个单独的类中为这些接口提供实现,并使用GLSurfaceView.setRenderer()方法将它依附到GLSurfaceView实例对象上。
    我们需要实现GLSurfaceView.Renderer的以下方法:
    a)     onSurfaceCreated():系统在创建GLSurfaceView时调用它一次。我们可以使用它来设置OpenGL的环境变量,或是初始化OpenGL的图形物体。
    b)     onDrawFrame():系统在每次重绘GLSurfaceView时调用这个方法。这个方法主要完成绘制图形的操作。
    c)     onSurfaceChanged():系统在GLSurfaceView的几何属性发生改变时调用该方法,包括大小或是设备屏幕的方向发生变化。例如,系统在屏幕从直立变为水平使调用它。这个方法主要用来对GLSurfaceView容器的变化进行响应。

你可能感兴趣的:(Android)