歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Android圖形系統之Surface、SurfaceView、SurfaceHolder及SurfaceHolder.Callback之間的聯系

1、Surface


Surface

extends Object
implements Parcelable java.lang.Object    ↳ Android.view.Surface

Class Overview


Handle 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成員變量

  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;  
    //@\frameworks\base\core\java\android\view\Surface.java
    // The mSurfaceControl will only be present for Surfaces used by the window
    // server or system processes. When this class is parceled we defer to the
    // mSurfaceControl to do the parceling. Otherwise we parcel the
    // mNativeSurface.
    private int mSurfaceControl;
    private int mSaveCount;
    private Canvas mCanvas;
    private int mNativeSurface;
    private int mSurfaceGenerationId;
    private String mName;

1.3、 理解Canvas對象,可以把它當做畫布,Canvas的方法大多數是設置畫布的大小、形狀、畫布背景顏色等等,要想在畫布上面畫畫,一般要與Paint對象結合使用,顧名思義,Paint就是畫筆的風格,顏料的色彩之類的。

  1. // 創建畫筆     
  2. Paint paint = new Paint();    
  3. paint.setColor(Color.RED);// 設置紅色     
  4.   
  5. canvas.drawCircle(602010, paint);// 畫一個圓    

1.4、Surface本身的作用類似一個句柄,得到了這個句柄就可以得到其中的Canvas、原生緩沖器以及其它方面的內容。


1.5、Surface實現了Parcelable接口,(implements Parcelable),也就是說Surface對象可以把顯示內容的數據寫入到 Parcel 中,並且能夠從Parcel讀回數據。

Parcelable

android.os.Parcelable Known Indirect Subclasses AbsSavedState,AbsoluteSizeSpan,AccessibilityEvent,AccessibilityNodeInfo,AccessibilityServiceInfo,Account,AccountAuthenticatorResponse,ActivityInfo,ActivityManager.MemoryInfo,ActivityManager.ProcessErrorStateInfo,ActivityManager.RecentTaskInfo,ActivityManager.RunningAppProcessInfo,ActivityManager.RunningServiceInfo, ActivityManager.RunningTaskInfo, and 144 others.

Class Overview


Interface 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


SurfaceView

extends View
java.lang.Object    ↳ android.view.View      ↳ android.view.SurfaceView Known Direct Subclasses GLSurfaceView,RSSurfaceView,VideoView

Class Overview


Provides 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就是把這些數據顯示出來到屏幕上面。

兩者聯系如圖所示:

Copyright © Linux教程網 All Rights Reserved