View與SurfaceView

一、View和SurfaceView的區別View只能在UI主線程進行修改,在後臺線程不可以修改UI元素。其中View子類實現修改主要通過複寫View的onDraw()方法。

SurfaceView可以通過後臺線程進行相關的線程進行修改。主要通過獲得SurfaceHolder對象來獲取Canvas對象,SurfaceView的子類實現SurfaceView.CallBack接口來實現Surface對象的創建、改變、銷燬等狀態的處理。SurfaceView比較適合:界面需要迅速更新、對幀率要求比較高的情況。使用SurfaceView需要主要以下幾點情況:
(1)SurfaceView和SurfaceHolder.Callback接口中的函數都是從當前線程中調用的(一般而言就是程序的主線程)。有關資源狀態要注意和繪製線程之間保持同步。
(2)在繪製線程中必須先合法化的獲取SurfaceHolder才能開始繪製內容,合法的狀態是在以下的兩個狀態SurfaceHolder.Callback.surfaceCreated()和SurfaceHolder.Callback.surfaceDestroyed()之間。另外Surface的類型爲SURFACE_TYPE_PUSH_BUFFERS的時候不合法。額外的繪製線程會消耗系統資源,在使用SurfaceView的注意

二、使用SurfaceView

只要繼承SurfaceView類並且實現SurfaceHolder.Callback接口就可以實現自定義的SurfaceView。SurfaceHolder.Callback在底層Surface狀態發生變化的時候會通知View。SurfaceHolder.Callback具有以下接口:
surfaceCreated(SurfaceHolder holder): 當Surface第一次創建後會立即調用該函數。程序在該函數中可以實現一些界面繪製相關的初始化工作,一般情況下都在另外的線程來繪製界面,所以在不在這個函數中繪製Surface。而會啓動額外的線程,來實現界面的繪製。
surfaceDestroyed(SurfaceHolder holder):當Surface被摧毀時調用該函數,該函數調用後就不能繼續使用Surface了,一般會把繪製的線程停止和清理使用的資源。
surfaceChanged(SurfaceHolder holder,int format,int width,int height):當Surface的狀態發生變化時就會調用該函數,在surfaceCreated調用該函數至少一次。一般不會再該函數中對界面做處理。
       通過SurfaceView的getHolder()函數可以獲取SurfaceHolder對象,Surface 就在SurfaceHolder對象內。雖然Surface保存了當前窗口的像素數據,但是在使用過程中是不直接和Surface打交道的,由SurfaceHolder的Canvas lockCanvas()或則Canvas lockCanvas(Rect dirty)函數來獲取Canvas對象,通過在Canvas上繪製內容來修改Surface中的數據。如果Surface不可編輯或則尚未創建調用該函數會返回null,在 unlockCanvas() 和 lockCanvas()中Surface的內容是不緩存的,所以需要完全重繪Surface的內容,爲了提高效率只重繪變化的部分則可以調用lockCanvas(Rect dirty)函數來指定一個dirty區域,這樣該區域外的內容會緩存起來。在調用lockCanvas函數獲取Canvas後,SurfaceView會獲取Surface的一個同步鎖直到調用unlockCanvasAndPost(Canvas canvas)函數才釋放該鎖,這裏的同步機制保證在Surface繪製過程中不會被改變(被摧毀、修改)。
       當在Canvas中繪製完成後,調用函數unlockCanvasAndPost(Canvas canvas)來通知系統Surface已經繪製完成,這樣系統會把繪製完的內容顯示出來。爲了充分利用不同平臺的資源,發揮平臺的最優效果可以通過SurfaceHolder的setType函數來設置繪製的類型,目前接收如下的參數:
SURFACE_TYPE_NORMAL:用RAM緩存原生數據的普通Surface
SURFACE_TYPE_HARDWARE:適用於DMA(Direct memory access )引擎和硬件加速的Surface
SURFACE_TYPE_GPU:適用於GPU加速的Surface
SURFACE_TYPE_PUSH_BUFFERS:表明該Surface不包含原生數據,Surface用到的數據由其他對象提供,在Camera圖像預覽中就使用該類型的Surface,有Camera負責提供給預覽Surface數據,這樣圖像預覽會比較流暢。如果設置這種類型則就不能調用lockCanvas來

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章