Android图形系统之SurfaceSurfaceViewSurfaceHolder及SurfaceHolder.Callback之间的联系

家资是何物,积帙列梁梠。这篇文章主要讲述Android图形系统之SurfaceSurfaceViewSurfaceHolder及SurfaceHolder.Callback之间的联系相关的知识,希望能为你提供帮助。
1、Surface
 
 

Surface extends  Object
implements  Parcelable
java.lang.Object
      ? android.view.Surface
Class OverviewHandle onto a raw buffer that is being managed by the screen compositor.
简单翻译:
Surface是原始图像缓冲区(raw buffer)的一个句柄,而原始图像缓冲区是由屏幕图像合成器(screen compositor)管理的。


1.1、 就如在C语言编程一样,通过一个文件的句柄,就可以操作文件,获取文件的内容。 同样的,通过Surface就可以获取raw buffer其中的内容。原生缓冲区(raw buffer)存储着当前窗口的像素数据。
 
 
1.2、事实上,当得到一个Surface对象时,同时会得到一个Canvas(画布)对象。这一点可以通过查看\frameworks\base\core\Java\Android\view\Surface.java文件可知道Surface类定义了一个Canvas成员变量
 
[java]  view plain  copy     print?
Android图形系统之SurfaceSurfaceViewSurfaceHolder及SurfaceHolder.Callback之间的联系

文章图片
Android图形系统之SurfaceSurfaceViewSurfaceHolder及SurfaceHolder.Callback之间的联系

文章图片
  1. //@\frameworks\base\core\java\android\view\Surface.java   
  2. //  The  mSurfaceControl  will  only  be  present  for  Surfaces  used  by  the  window   
  3. //  server  or  system  processes.  When  this  class  is  parceled  we  defer  to  the   
  4. //  mSurfaceControl  to  do  the  parceling.  Otherwise  we  parcel  the   
  5. //  mNativeSurface.   
  6. private  int  mSurfaceControl;    
  7. private  int  mSaveCount;    
  8. private  Canvas  mCanvas;    
  9. private  int  mNativeSurface;    
  10. private  int  mSurfaceGenerationId;    
  11. private  String  mName;    
 
 
1.3、 理解Canvas对象,可以把它当做画布,Canvas的方法大多数是设置画布的大小、形状、画布背景颜色等等,要想在画布上面画画,一般要与Paint对象结合使用,顾名思义,Paint就是画笔的风格,颜料的色彩之类的。
 
[java]  view plain  copy     print?
Android图形系统之SurfaceSurfaceViewSurfaceHolder及SurfaceHolder.Callback之间的联系

文章图片
Android图形系统之SurfaceSurfaceViewSurfaceHolder及SurfaceHolder.Callback之间的联系

文章图片
  1. //  创建画笔       
  2. Paint  paint  =  new  Paint();        
  3. paint.setColor(Color.RED); //  设置红色       
  4.    
  5. canvas.drawCircle(60,  20,  10,  paint); //  画一个圆       



 
1.4、Surface本身的作用类似一个句柄,得到了这个句柄就可以得到其中的Canvas、原生缓冲器以及其它方面的内容。
 
1.5、Surface实现了Parcelable接口,(implements  Parcelable),也就是说Surface对象可以把显示内容的数据写入到 Parcel 中,并且能够从Parcel读回数据。
 
Parcelable
android.os.Parcelable
Android图形系统之SurfaceSurfaceViewSurfaceHolder及SurfaceHolder.Callback之间的联系

文章图片
Known Indirect SubclassesAbsSavedState,AbsoluteSizeSpan,AccessibilityEvent,AccessibilityNodeInfo,AccessibilityServiceInfo,Account,AccountAuthenticatorResponse,ActivityInfo,ActivityManager.MemoryInfo,ActivityManager.ProcessErrorStateInfo,ActivityManager.RecentTaskInfo,ActivityManager.RunningAppProcessInfo,ActivityManager.RunningServiceInfo,ActivityManager.RunningTaskInfo, and  144 others.
Class OverviewInterface for classes whose instances can be written to and restored from a  Parcel. Classes implementing the Parcelable interface must also have a static field calledCREATOR, which is an object implementing theParcelable.Creator  interface.
简单翻译:
            实现这个接口的对象可以写入数据到Parcel,同时也可以把数据读出来。

 
 
 
2、SurfaceView
 
 
SurfaceViewextends  View
java.lang.Object
      ? android.view.View
        ? android.view.SurfaceView
Android图形系统之SurfaceSurfaceViewSurfaceHolder及SurfaceHolder.Callback之间的联系

文章图片
Known Direct SubclassesGLSurfaceView,RSSurfaceView,VideoView
Class OverviewProvides a dedicated drawing surface embedded inside of a view hierarchy. You can control the format of this surface and, if you like, its size; the SurfaceView takes care of placing the surface at the correct location on the screen
The surface is Z ordered so that it is behind the window holding its SurfaceView; the SurfaceView punches a hole in its window to allow its surface to be displayed. The view hierarchy will take care of correctly compositing with the Surface any siblings of the SurfaceView that would normally appear on top of it. This can be used to place overlays such as buttons on top of the Surface, though note however that it can have an impact on performance since a full alpha-blended composite will be performed each time the Surface changes.
Access to the underlying surface is provided via the SurfaceHolder interface, which can be retrieved by callinggetHolder().
The Surface will be created for you while the SurfaceView‘s window is visible; you should implementsurfaceCreated(SurfaceHolder)andsurfaceDestroyed(SurfaceHolder)  to discover when the Surface is created and destroyed as the window is shown and hidden.
One of the purposes of this class is to provide a surface in which a secondary thread can render into the screen. If you are going to use it this way, you need to be aware of some threading semantics:
  • All SurfaceView and  SurfaceHolder.Callback  methods will be called from the thread running the SurfaceView‘s window (typically the main thread of the application). They thus need to correctly synchronize with any state that is also touched by the drawing thread.
  • You must ensure that the drawing thread only touches the underlying Surface while it is valid -- betweenSurfaceHolder.Callback.surfaceCreated()  andSurfaceHolder.Callback.surfaceDestroyed().
简单翻译:
                  SurfaceView提供了一个专门用于绘制的surface,这个surface内嵌于。你可以控制这个Surface的格式和尺寸。Surfaceview控制这个Surface在屏幕的正确绘制位置。

              surface是Z-ordered的(也就是说在xyz坐标系中,按照Z坐标排序的,Z值大的表面覆盖在Z值小的表面的上方),这表明它总在自己所在窗口的后面。surfaceview在显示窗口处为Surface提供了一个可见区域,通过这个区域,才能看到Surface里面的内容。可以放置一些覆盖图层(overlays)在Surface上面,如Button、Textview之类的。但是,需要注意的是,如果Surface上面有全透明的控件,那么随着Surface的每一次变化,这些全透明的控件就会重新渲染,这样的话,就影响性能与显示的效果。

              你可以通过SurfaceHolder这个接口去访问Surface,而执行getHolder()方法可以得到SurfaceHolder接口。

              当SurfaceView的窗口可见时,Surface就会被创建,当SurfaceView窗口隐藏时,Surface就会被销毁。当然了,你也可以通过复写surfaceCreated(SurfaceHolder)  和  surfaceDestroyed(SurfaceHolder)  这两个方法来验证一下Surface何时被创建与何时被销毁。

              SurfaceView提供了一个运行在渲染线程的surface,若你要更新屏幕,你需要了解以下线程知识。
  • 所有SurfaceView 和  SurfaceHolder.Callback的方法都应该在主线程(UI线程)里面调用,应该要确保渲染进程所访问变量的同步性。
  • 你必须确保只有当Surface有效的时候,(也就是当Surface的生命周期在SurfaceHolder.Callback.surfaceCreated()  和SurfaceHolder.Callback.surfaceDestroyed()之间)才能让渲染进程访问。
 
 
2.1、SurfaceView与Surface的联系

简单来说,SurfaceView与Surface的联系就是,Surface是管理显示内容的数据(implementsParcelable),包括存储于数据的交换。而SurfaceView就是把这些数据显示出来到屏幕上面。
两者联系如图所示:
Android图形系统之SurfaceSurfaceViewSurfaceHolder及SurfaceHolder.Callback之间的联系

文章图片

 
3、SurfaceHolder
 
SurfaceHolder
android.view.SurfaceHolder
Class OverviewAbstract interface to someone holding a display surface. Allows you to control the surface size and format, edit the pixels in the surface, and monitor changes to the surface. This interface is typically available through theSurfaceView  class.
When using this interface from a thread other than the one running its  SurfaceView, you will want to carefully read the methodslockCanvas()andCallback.surfaceCreated().
简单翻译:
              SurfaceHolder是控制surface的一个抽象接口,你可以通过SurfaceHolder来控制surface的尺寸和格式,或者修改surface的像素,监视surface的变化等等,SurfaceHolder是SurfaceView的典型接口。

              与直接控制SurfaceView来修改surface不同,使用SurfaceHolder来修改surface时,需要注意lockCanvas()  和Callback.surfaceCreated().这两个方法。
 
SurfaceHolder控制surface的流程所使用的几个方法。
 
3.1、abstract void      addCallback(SurfaceHolder.Callback callback)
                        Add a Callback interface for this holder.// 给SurfaceHolder一个回调对象。

3.2、abstract Canvas      lockCanvas(Rect dirty)
                          Just like lockCanvas() but allows specification of a dirty rectangle.
                          // 锁定画布中的某一个区域,返回的画布对象Canvas(当更新的内容只有一个区域时,同时要追求高效,可以只更
                      新一部分的区域,而不必更新全部画布区域)

3.3、abstract Canvas      lockCanvas()
                          Start editing the pixels in the surface.// 锁定画布,返回的画布对象Canvas

3.4、abstract void      removeCallback(SurfaceHolder.Callback callback)
                          Removes a previously added Callback interface from this holder.//移除回调对象

3.5、abstract void      unlockCanvasAndPost(Canvas canvas)
                          Finish editing pixels in the surface.// 结束锁定画图,并提交改变。
 
 
4、SurfaceHolder.Callback


 
SurfaceHolder.Callback
android.view.SurfaceHolder.Callback
Android图形系统之SurfaceSurfaceViewSurfaceHolder及SurfaceHolder.Callback之间的联系

文章图片
Known Indirect SubclassesGLSurfaceView,NativeActivity,RSSurfaceView,SurfaceHolder.Callback2
Class OverviewA client may implement this interface to receive information about changes to the surface. When used with aSurfaceView, the Surface being held is only available between calls tosurfaceCreated(SurfaceHolder)andsurfaceDestroyed(SurfaceHolder). The Callback is set withSurfaceHolder.addCallback  method.
简单翻译:
SurfaceHolder.Callback是监听surface改变的一个接口
 
 
4.1、public abstract voidsurfaceChanged(SurfaceHolder  holder, int format, int width, int height)
holder The SurfaceHolder whose surface has changed.
format The new PixelFormat of the surface.
width The new width of the surface.
height The new height of the surfa
//surface发生改变时被调用

 
 
4.2、public abstract voidsurfaceCreated(SurfaceHolder  holder)
Parameters
holder The SurfaceHolder whose surface is being created
 
//在surface创建时被调用,一般在这个方法里面开启渲染屏幕的线程。
 
4.3、public abstract voidsurfaceDestroyed(SurfaceHolder  holder) Parameters
holder The SurfaceHolder whose surface is being destroyed.
    //销毁时被调用,一般在这个方法里将渲染的线程停止。

 
 
 
附上上述所说几种的联系方法
 
[java]  view plain  copy     print?
Android图形系统之SurfaceSurfaceViewSurfaceHolder及SurfaceHolder.Callback之间的联系

文章图片
Android图形系统之SurfaceSurfaceViewSurfaceHolder及SurfaceHolder.Callback之间的联系

文章图片
  1. SurfaceHolder  =  SurfaceView.getHolder();    
  2.    
  3. Surface  =  SurfaceHolder.getSurface();    
  4.    
  5. Canvas  =SurfaceHolder.LockCanvas(Rect  dirty)   
  6.    
  7. Canvas      =Surface.lockCanvas(Rect  dirty)   



 
5、Demo小程序
共有两个class效果图如下,具体看代码和注释。
 
进入程序,执行
 
[java]  view plain  copy     print?
Android图形系统之SurfaceSurfaceViewSurfaceHolder及SurfaceHolder.Callback之间的联系

文章图片
Android图形系统之SurfaceSurfaceViewSurfaceHolder及SurfaceHolder.Callback之间的联系

文章图片
  1. public  void  surfaceCreated(SurfaceHolder  holder)   
 
然后执行
 
[java]  view plain  copy     print?
Android图形系统之SurfaceSurfaceViewSurfaceHolder及SurfaceHolder.Callback之间的联系

文章图片
Android图形系统之SurfaceSurfaceViewSurfaceHolder及SurfaceHolder.Callback之间的联系

文章图片
  1. public  void  surfaceChanged(SurfaceHolder  holder,  int  format,  int  width,    int  height)   
 
退出程序调用surfaceDestroyed,释放资源。
[java]  view plain  copy     print?
Android图形系统之SurfaceSurfaceViewSurfaceHolder及SurfaceHolder.Callback之间的联系

文章图片
Android图形系统之SurfaceSurfaceViewSurfaceHolder及SurfaceHolder.Callback之间的联系

文章图片
  1. public  void  surfaceDestroyed(SurfaceHolder  holder)   



 
/****************************************************************/
效果图:
Android图形系统之SurfaceSurfaceViewSurfaceHolder及SurfaceHolder.Callback之间的联系

文章图片

 
@MySurfaceView.java
[java]  view plain  copy     print?
Android图形系统之SurfaceSurfaceViewSurfaceHolder及SurfaceHolder.Callback之间的联系

文章图片
Android图形系统之SurfaceSurfaceViewSurfaceHolder及SurfaceHolder.Callback之间的联系

文章图片
  1. /* 
  2.   *  author:  conowen 
  3.   *  e-mail:  [email  protected] 
  4.   *  date    :    2012.8.4 
  5.   */   
  6. package  com.conowen.SurfaceViewDemo;    
  7.    
  8. import  android.app.Activity;    
  9. import  android.os.Bundle;    
  10.    
  11. public  class  SurfaceViewDemoActivity  extends  Activity  {   
  12.         /**  Called  when  the  activity  is  first  created.  */   
  13.         @Override   
  14.         public  void  onCreate(Bundle  savedInstanceState)  {   
  15.                 super.onCreate(savedInstanceState);    
  16.               //  setContentView(R.layout.main);    
  17.                 setContentView(new  MySurfaceView(this));    
  18.                    
  19.         }   
  20. }   



@SurfaceViewDemoActivity.java
【Android图形系统之SurfaceSurfaceViewSurfaceHolder及SurfaceHolder.Callback之间的联系】 
[java]  view plain  copy     print?
Android图形系统之SurfaceSurfaceViewSurfaceHolder及SurfaceHolder.Callback之间的联系

文章图片
Android图形系统之SurfaceSurfaceViewSurfaceHolder及SurfaceHolder.Callback之间的联系

文章图片
  1. /* 
  2.   *  author:  conowen 
  3.   *  e-mail:  [email  protected] 
  4.   *  date    :    2012.8.4 
  5.   */   
  6. package  com.conowen.SurfaceViewDemo;    
  7.    
  8. import  android.content.Context;    
  9. import  android.graphics.Canvas;    
  10. import  android.graphics.Color;    
  11. import  android.graphics.Paint;    
  12. import  android.graphics.Rect;    
  13. import  android.util.Log;    
  14. import  android.view.SurfaceHolder;    
  15. import  android.view.SurfaceView;    
  16.    
  17. public  class  MySurfaceView  extends  SurfaceView  implements   
  18.                 SurfaceHolder.Callback  {   
  19.    
  20.         private  String  TAG  =  "conowen";    
  21.            
  22.         private  SurfaceHolder  sfh;    
  23.         private  boolean  ThreadFlag;    
  24.         private  int  counter;    
  25.         private  Canvas  canvas;    
  26.    
  27.         private  Thread  mThread  =  new  Thread(new  Runnable()  {   
  28.    
  29.                 @Override   
  30.                 public  void  run()  {   
  31.                         //  TODO  Auto-generated  method  stub   
  32.                         while  (ThreadFlag)  {   
  33.    
  34.                                 //  锁定画布,得到Canvas对象   
  35.                                 canvas  =  sfh.lockCanvas();    
  36.    
  37.                                 //  设定Canvas对象的背景颜色   
  38.                                 canvas.drawColor(Color.GREEN);    
  39.    
  40.                                 //  创建画笔   
  41.                                 Paint  p  =  new  Paint();    
  42.                                 //  设置画笔颜色   
  43.                                 p.setColor(Color.RED);    
  44.                                 //  设置文字大小   
  45.                                 p.setTextSize(40);    
  46.    
  47.                                 //  创建一个Rect对象rect   
  48.                                 //  public  Rect  (int  left,  int  top,  int  right,  int  bottom)   
  49.                                 Rect  rect  =  new  Rect(100,  50,  400,  350);    
  50.                                 //  在canvas上绘制rect   
  51.                                 canvas.drawRect(rect,  p);    
  52.                                 //  在canvas上显示时间   
  53.                                 //  public  void  drawText  (String  text,  float  x,  float  y,  Paint   
  54.                                 //  paint)   
  55.                                 canvas.drawText("时间  =  "  +  (counter++)  +  "  秒",  500,  200,  p);    
  56.    
  57.                                 if  (canvas  !=  null)  {   
  58.                                         //  解除锁定,并提交修改内容,更新屏幕   
  59.                                         sfh.unlockCanvasAndPost(canvas);    
  60.                                 }   
  61.                                 try  {   
  62.                                         Thread.sleep(1000);    
  63.                                 }  catch  (InterruptedException  e)  {   
  64.                                         //  TODO  Auto-generated  catch  block   
  65.                                         e.printStackTrace();    
  66.                                 }   
  67.                         }   
  68.                 }   
  69.    
  70.         });    
  71.    
  72.         public  MySurfaceView(Context  context)  {   
  73.                 super(context);    
  74.                 //  TODO  Auto-generated  constructor  stub   
  75.    
  76.                 //  通过SurfaceView获得SurfaceHolder对象   
  77.                 sfh  =  this.getHolder();    
  78.    
  79.                 //  为SurfaceHolder添加回调结构SurfaceHolder.Callback   
  80.                 sfh.addCallback(this);    
  81.    
  82.         }   
  83.    
  84.         @Override   
  85.         public  void  surfaceChanged(SurfaceHolder  holder,  int  format,  int  width,   
  86.                         int  height)  {   
  87.                 //  TODO  Auto-generated  method  stub   
  88.                 Log.i(TAG,  "surfaceChanged");    
  89.    
  90.         }   
  91.    
  92.         @Override   
  93.         public  void  surfaceCreated(SurfaceHolder  holder)  {   
  94.                 //  TODO  Auto-generated  method  stub   
  95.                 Log.i(TAG,  "surfaceCreated");    
  96.                 counter  =  0;    
  97.                 ThreadFlag  =  true;    
  98.                 mThread.start();    
  99.    
  100.         }   
  101.    
  102.         @Override   
  103.         public  void  surfaceDestroyed(SurfaceHolder  holder)  {   
  104.                 //  TODO  Auto-generated  method  stub   
  105.                 Log.i(TAG,  "surfaceDestroyed");    
  106.                 ThreadFlag  =  false;    
  107.    
  108.         }   
  109.    
  110. }   
Android图形系统之SurfaceSurfaceViewSurfaceHolder及SurfaceHolder.Callback之间的联系

文章图片
















































    推荐阅读