View,SurfaceView,GLSurfaceView有什么区别?
1)View
View类是Android的一个非常重要的超类,它是Android里所有与用户交互的控件的父类,包括Widget类的交互UI控件(按钮、文本框等)和ViewGroup类布局控件。SurfaceView继承自View,GLSurfaceView继承自SurfaceView。
2)SurfaceView
2.1SurfaceView概述
普通的Android控件,例如TextView、Button和CheckBox等,它们都是将自己的UI绘制在宿主窗口的绘图表面之上,这意味着它们的 UI是在应用程序的主线程中进行绘制的。由于应用程序的主线程除了要绘制 UI之外,还需要及时地响应用户输入,否则的话,系统就会认为应用程序没有响应了,因此就会弹出一个 ANR对话框出来。对于一些游戏画面,或者摄像头预览、视频播放来说,它们的 UI都比较复杂,而且要求能够进行高效的绘制,因此,它们的 UI就不适合在应用程序的主线程中进行绘制。这时候就必须要给那些需要复杂而高效 UI的视图生成一个独立的绘制这些视图的UI
2.2 SurfaceView 的大致实现原理
Android应用程序窗口是通过 SurfaceFlinger服务来绘制自己的UI的。一般来说,每一个窗口在 SurfaceFlinger服务中都对应有一个 Layer,用来描述它的绘图表面。对于那些具有 SurfaceView的窗口来说,每一个 SurfaceView在SurfaceFlinger服务中还对应有一个独立的Layer或者LayerBuffer,用来单独描述它的绘图表面,以区别于它的宿主窗口的绘图表面。
无论是LayerBuffer,还是Layer,它们都是以LayerBase为基类的,也就是说,SurfaceFlinger服务把所有的LayerBuffer和Layer都抽象为LayerBase,因此就可以用统一的流程来绘制和合成它们的UI。
我们假设在一个Activity窗口的视图结构中,除了有一个DecorView顶层视图之外,还有两个TextView控件,以及一个SurfaceView视图,这样该Activity窗口在SurfaceFlinger服务中就对应有两个Layer或者一个Layer的在SurfaceFlinger服务中还对应有一个独立的Layer或者LayerBuffer,用来单独描述它的绘图表面,以区别于它的宿主窗口的绘图表面。无论是LayerBuffer,还是Layer,它们都是以LayerBase为基类的,也就是说,SurfaceFlinger服务把所有的LayerBuffer和Layer都抽象为LayerBase,因此就可以用统一的流程来绘制和合成它们的UI。
我们假设在一个Activity窗口的视图结构中,除了有一个DecorView顶层视图之外,还有两个TextView控件,以及一个SurfaceView视图,这样该Activity窗口在SurfaceFlinger服务中就对应有两个Layer或者一个Layer的一个LayerBuffer,如图所示:
在图中,Activity窗口的顶层视图 DecorView及其两个 TextView控件的 UI都是绘制在 SurfaceFlinger服务中的同一个 Layer上面的,而 SurfaceView的 UI是绘制在 SurfaceFlinger服务中的另外一个 Layer或者 LayerBuffer上的。
注意,用来描述 SurfaceView的 Layer或者 LayerBuffer的 Z轴位置是小于用来其宿主 Activity窗口的 Layer
的Z轴位置的,但是前者会在后者的上面挖一个“洞”出来,以便它的UI可以对用户可见。实际上,SurfaceView在其宿主Activity窗口上所挖的“洞”只不过是在其宿主Activity窗口上设置了一块透明区域。
2.3SurfaceView的简单使用
a.获取到SurfaceView对应的SurfaceHolder,给SurfaceHolder添加一个SurfaceHolder.callback对象。
b.创建渲染线程对象
c.在子线程中开始在Surface上面绘制图形,因为SurfaceView没有对我们暴露Surface,而只是暴露了Surface的包装器SurfaceHolder,所以使用SurfaceHolder的lockCanvas()获取Surface上面指定区域的Canvas,在该Canvas上绘制图形,绘制结束后,使用SurfaceHolder的unlockCanvasAndPost()方法解锁Canvas,并且让UI线程把Surface上面的东西绘制到View的Canvas上面。示例代码如下:
1.publicclassGameUIextendsSurfaceViewimplementsSurfaceHolder.Callback{
2.privateSurfaceHolderholder;
3.privateRenderThreadrenderThread;
4.privatebooleanisDraw=false;//控制绘制的开关
5.publicGameUI(Contextcontext){
6.super(context);holder=this.getHolder();
7.holder.addCallback(this);
8.renderThread=newRenderThread();
9.}
10.@OverridepublicvoidsurfaceChanged(SurfaceHolderholder,intformat,intwidth,intheight)
11.{}
12.@OverridepublicvoidsurfaceCreated(SurfaceHolderholder){
13.isDraw=true;
14.renderThread.start();
15.}
16.@OverridepublicvoidsurfaceDestroyed(SurfaceHolderholder){
230
17.isDraw=false;
18.}
19./**
20.*绘制界面的线程
21.*
22.*@authorAdministrator23.*
24.*/
25.privateclassRenderThreadextendsThread{
26.@Overridepublicvoidrun(){
27.//不停绘制界面
28.while(isDraw){
29.drawUI();
30.}
31.super.run();
32.}
33.}
34./**
35.*界面绘制
36.*/
37.publicvoiddrawUI(){
38.Canvascanvas=holder.lockCanvas();
39.try{
40.drawCanvas(canvas);
41.}catch(Exceptione){
42.e.printStackTrace();
43.}finally{
44.holder.unlockCanvasAndPost(canvas);
45.}
46.}
47.privatevoiddrawCanvas(Canvascanvas){
48.//在canvas上绘制需要的图形
49.}
50.}
3)
GLSurfaceView
3.1GLSurfaceView概述
GLSurfaceView是一个视图,继承至 SurfaceView,它内嵌的 surface专门负责 OpenGL渲染。GLSurfaceView提供了下列特性:
1>管理一个 surface,这个 surface就是一块特殊的内存,能直接排版到 Android的视图 view上。
2>管理一个 EGL display,它能让 opengl把内容渲染到上述的 surface上。
3>用户自定义渲染器(render)。
4>让渲染器在独立的线程里运作,和 UI线程分离。
5>支持按需渲染(on-demand)和连续渲染(continuous)。
6>一些可选工具,如调试。