请教view,SurfaceView,GLSurfaceView的关系和区别

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了请教view,SurfaceView,GLSurfaceView的关系和区别相关的知识,希望对你有一定的参考价值。

如果你的游戏不吃CPU,用View就比较好,符合标准android操作方式,由系统决定刷新surface的时机。
  但如果很不幸的,你做不到不让你的程序吃CPU,你就只好使用SurfaceView来强制刷新surface了,不然系统的UI进程很可能抢不过你那些吃CPU的线程。
  当然其实不止这两种方法来刷新Surface的,这两种只是纯Java应用比较常见的方法。
  SurfaceView和View最本质的区别在于,surfaceView是在一个新起的单独线程中可以重新绘制画面而View必须在UI的主线程中更新画面。
  那么在UI的主线程中更新画面 可能会引发问题,比如你更新画面的时间过长,那么你的主UI线程会被你正在画的函数阻塞。那么将无法响应按键,触屏等消息。
  当使用surfaceView 由于是在新的线程中更新画面所以不会阻塞你的UI主线程。但这也带来了另外一个问题,就是事件同步。比如你触屏了一下,你需要surfaceView中 thread处理,一般就需要有一个event queue的设计来保存touch event,这会稍稍复杂一点,因为涉及到线程同步。
  所以基于以上,根据游戏特点,一般分成两类。
  1 被动更新画面的。比如棋类,这种用view就好了。因为画面的更新是依赖于 onTouch 来更新,可以直接使用 invalidate。 因为这种情况下,这一次Touch和下一次的Touch需要的时间比较长些,不会产生影响。
  2 主动更新。比如一个人在一直跑动。这就需要一个单独的thread不停的重绘人的状态,避免阻塞main UI thread。所以显然view不合适,需要surfaceView来控制。
  一般2D游戏开发使用SurfaceView足够,因为它也是google专们扩展用于2D游戏开发的画布
  使用普通的游戏画布(Android中2D专用游戏画布)中进行绘制图片,然后在GLSurfaceView(Android中3D游戏专用画布)中渲染图片的对比中发现GLSurfaceView的效率高于SurfaceView的30倍;GLSurfaceView的效率主要是因为机器硬件的GPU加速,现在flash技术也有了GPU加速技术;
  下面总结一下:
  一般2D游戏使用SurfaceView足够,所以不要认为什么都要使用GLSurfaceView(openGL),而且 GLSurfaceView的弊端在于适配能力差,因为很多机型中是没有GPU加速的。
参考技术A 参考如下内容:
Android游戏当中主要的除了控制类外就是显示类View。SurfaceView是从View基类中派生出来的显示类。android游戏开发中常用的三种视图是:view、SurfaceView和GLSurfaceView。
  View:显示视图,内置画布,提供图形绘制函数、触屏事件、按键事件函数等;必须在UI主线程内更新画面,速度较慢。
  SurfaceView:基于view视图进行拓展的视图类,更适合2D游戏的开发;是view的子类,类似使用双缓机制,在新的线程中更新画面所以刷新界面速度比view快。
  GLSurfaceView:基于SurfaceView视图再次进行拓展的视图类,专用于3D游戏开发的视图;是SurfaceView的子类,openGL专用。
  
  在2D游戏开发中,大致可以分为两种游戏框架,View和SurfaceView。 View和SurfaceView区别:
  View:必须在UI的主线程中更新画面,用于被动更新画面。
  surfaceView:UI线程和子线程中都可以。在一个新启动的线程中重新绘制画面,主动更新画面。

UI的主线程中更新画面 可能会引发问题,比如你更新画面的时间过长,那么你的主UI线程会被你正在画的函数阻塞。那么将无法响应按键,触屏等消息。
当使用surfaceView 由于是在新的线程中更新画面所以不会阻塞你的UI主线程。但这也带来了另外一个问题,就是事件同步,涉及到线程同步。

所以基于以上,根据游戏特点,一般分成两类。

1 被动更新画面的。比如棋类,这种用view就好了。因为画面的更新是依赖于 onTouch 来更新,可以直接使用 invalidate。 因为这种情况下,这一次Touch和下一次的Touch需要的时间比较长些,不会产生影响。

2 主动更新。比如一个人在一直跑动。这就需要一个单独的thread不停的重绘人的状态,避免阻塞main UI thread。所以显然view不合适,需要surfaceView来控制。
参考技术B View:显示视图,内置画布,提供图形绘制函数、触屏事件、按键事件函数等;必须在UI主线程内更新画面,速度较慢

SurfaceView:基于view视图进行拓展的视图类,更适合2D游戏的开发;是view的子类,类似使用双缓机制,在新的线程中更新画面所以刷新界面速度比view快。
GLSurfaceView:基于SurfaceView视图再次进行拓展的视图类,专用于3D游戏开发的视图;是SurfaceView的子类,openGL专用。
在2D游戏开发中,大致可以分为两种游戏框架,View和SurfaceView。 View和SurfaceView区别:
View:必须在UI的主线程中更新画面,用于被动更新画面。

surfaceView:UI线程和子线程中都可以。在一个新启动的线程中重新绘制画面,主动更新画面。

android: View, SurfaceView, GLSurfaceView, TextureView 区别与联系

区别与联系

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

SurfaceView: 基于view视图进行拓展的视图类,更适合2D游戏的开发,是view的子类,使用了双缓冲机制,即:允许在子线程中更新画面,所以刷新界面速度比view快。

GLSurfaceView: 基于SurfaceView视图再次进行拓展的视图类,在SurfaceView基础上封装了EGL环境管理以及render线程,专用于3D游戏开发的视图。是SurfaceView的子类,openGL专用。

TextrueView: 前面的SurfaceView的工作方式是创建一个置于应用窗口之后的新窗口,脱离了Android的普通窗口,因此无法对其应用变换操作(平移、缩放、旋转等),而TextureView则解决了此问题,Android4.0引入。

 

PS: UI线程(即主线程)中更新画面有时可能会引发问题,比如你需要更新画面的时间过长,那么UI线程会被你正在画的函数阻塞,那么将无法响应按键,触屏等消息。而SurfaceView 系的API由于是在新的线程中更新画面所以不会阻塞你的UI线程。但这也带来了另外一个问题,就是事件同步,涉及到线程同步。

 

应用场景:

以游戏举例:

1 被动更新画面的。比如棋类,这种用View就好了。因为画面的更新是依赖于 onTouch 来更新,可以直接使用 invalidate。 在这种情况下,这一次Touch和下一次的Touch需要的时间比较长些,不会产生影响。

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

3.对于一些3D游戏来说,为了追求极致的性能和帧率,可以使用GLSurfaceView。其本身就封装了一些OpenGL ES的API, 通过着色器可以达到很多View难以达到的效果。

4.SurfaceView窗口刷新的时候不需要重绘应用程序的窗口(android普通窗口的视图绘制机制是一层一层的,任何一个子元素或者是局部的刷新都会导致整个视图结构全部重绘一次,因此效率非常低下,不过满足普通应用界面的需求还是绰绰有余),但是SurfaceView也有一些非常不便的限制。因为SurfaceView的内容不在应用窗口上,所以不能使用变换(平移、缩放、旋转等),所以如果是对于视频播放器或者相机应用的开发,TextureView更加适合。


参考链接:

 

以上是关于请教view,SurfaceView,GLSurfaceView的关系和区别的主要内容,如果未能解决你的问题,请参考以下文章

讲讲Android为自定义view提供的SurfaceView

讲讲Android为自定义view提供的SurfaceView

android从view切换surfaceview的时候,出现短暂的黑屏,怎么处理

View.SurfaceView,为啥它的成员mSurfaceHolder从getSurface()返回null?

android: View, SurfaceView, GLSurfaceView, TextureView 区别与联系

尝试在空对象引用上调用虚拟方法 'android.view.SurfaceHolder android.view.SurfaceView.getHolder()'