Android SurfaceView基礎用法詳解

Android 遊戲開發框架核心組件

這裡寫圖片描述

核心組件介紹

SurfaceView 介紹

  1. SurfaceView 介紹 SurfaceView 就是帶 Surface 的 view,它是一個 View,是 View 的子類,所以和其他 View 一樣,可以在屏幕上展示東西接收用戶輸入,具有 View 的生命周期回調函數,如 onMeasure、onLayout、onDraw、onTouchEvent 等
  2. SurfaceView 帶有獨立的 Surface(獨立與 window 的 surface),這可以讓子線程在獨立的 Surface 上面繪制東西,進行 SurfaceView 的界面繪制,這個子線程就叫做渲染線程,但是要讓獨立的 Surface 上面的東西在 View 上面展示出來,需要 post 一個消息給主線程,目的是把該 Surface 中 canvas 上的東西繪制到 View 的真正的畫佈上面(window 的 surface 的 canvas上),這樣就可以把 UI 線程空閑出來處理用戶的交互
  3. Surface 可能被銷毀,它隻在SurfaceHolder.Callback.surfaceCreated() 和 SurfaceHolder.Callback.surfaceDestroyed() 之間有效,這隻是說 Surface 創建和銷毀的時候會回到前面兩個方法,所以要確保渲染線程訪問的是合法有效的 surface
  4. SurfaceHolder.CallBack 是通過 SurfaceView 的 SurfaceHolder 的 addCallback 來設置給 SurfaceHolder 的,讓 SurfaceView 實現 CallBack 並設置給 SurfaceHolder,SurfaceView 就可以監聽這個獨立 Surface 的創建和銷毀瞭。

sdk 中的介紹

SurfaceView是視圖(View)的繼承類,這個視圖裡內嵌瞭一個專門用於繪制的Surface。你可以控制這個Surface的格式和尺寸。Surfaceview控制這個Surface的繪制位置。
surface是縱深排序(Z-ordered)的,這表明它總在自己所在窗口的後面。surfaceview提供瞭一個可見區域,隻有在這個可見區域內 surface 部分內容才可見,可見區域外的部分不可見。
surface 的排版顯示受到視圖層級關系的影響,它的兄弟視圖結點會在頂端顯示。這意味者 surface
的內容會被它的兄弟視圖遮擋,這一特性可以用來放置遮蓋物(overlays)(例如,文本和按鈕等控件)。註意,如果 surface 上面有透明控件,那麼它的每次變化都會引起框架重新計算它和頂層控件之間的透明效果,這會影響性能。
你可以通過 surfaceHolder 接口訪問這個surface,getHolder() 方法可以得到這個接口。
surfaceview 變得可見時,surface被創建;surfaceview隱藏前,surface被銷毀。這樣能節省資源。如果你要查看 surface 被創建和銷毀的時機,可以重載surfaceCreated(SurfaceHolder)和 surfaceDestroyed(SurfaceHolder) surfaceView 的核心在於提供瞭兩個線程:UI線程和渲染線程。
這裡應註意:
1. 所有 SurfaceView 和 SurfaceHolder.Callback 的方法都會在UI線程裡調用,一般來說就是應用程序主線程。所以渲染線程所要訪問的各種變量應該作同步處理。
2. 由於surface可能被銷毀,它隻在SurfaceHolder.Callback.surfaceCreated()和 SurfaceHolder.Callback.surfaceDestroyed()之間有效,所以要確保渲染線程訪問的是合法有效的
surface。

SurfaceHolder 介紹

SurfaceHolder 是對 SurfaceView 的 Surface 的包裝,不但在 SurfaceHolder.callback 接口中負責 Surface 創建和銷毀的回調,而且還對 Surface 的關鍵方法 LockCanvas()、unLockCanvasAndPost() 方法進行瞭線程安全的包裝,所以 SurfaceHolder 是 Surface 對象的持有者,負責 Surface 的生命周期中的對 Surface 操作的方法的調用
臟矩形 Rect dirty,是指標記這塊矩形區域的數據作廢,也就是需要重寫繪制的矩形區域,LockCanvas(Rect dirty),可以指定一個矩形區域,讓 Surface 中的 Canvas 上部分數據重繪。

SurfaceView、SurfaceHolder、Surface 之間的關系

這裡寫圖片描述

SurfaceView 使用的步驟

  1. 獲取到 SurfaceView 對應的 SurfaceHolder,給 SurfaceHolder 添加一個 SurfaceHolder.callback 對象。
  2. 創建渲染線程對象
  3. 在子線程中開始在 Surface 上面繪制圖形,因為SurfaceView沒有對我們暴露 Surface,而隻是暴露瞭 Surface 的包裝器 SurfaceHolder,所以使用 SurfaceHolder 的 lockCanvas()獲取 Surface 上面指定區域的 Canvas,在該 Canvas 上繪制圖形,繪制結束後,使用 SurfaceHolder 的 unlockCanvasAndPost()方法解鎖 Canvas,並且讓 UI 線程把 Surface 上面的東西繪制到 View 的 Canvas 上面

SurfaceView 使用的 demo

public class GameUI extends SurfaceView implements SurfaceHolder.Callback {

    private SurfaceHolder holder;
    private RenderThread renderThread;
    private boolean isDraw = false;// 控制繪制的開關

    public GameUI(Context context) {
        super(context);
        holder = this.getHolder();
        holder.addCallback(this);

        renderThread = new RenderThread();
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        isDraw = true;
        renderThread.start();

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        isDraw = false;

    }

    /**
    * 繪制界面的線程
    * 
    * @author Administrator
    * 
    */
    private class RenderThread extends Thread {
        @Override
        public void run() {
            // 不停繪制界面
            while (isDraw) {
                drawUI();
            }
            super.run();
        }
    }

    /**
    * 界面繪制
    */
    public void drawUI() {
        Canvas canvas = holder.lockCanvas();
        try {
            drawCanvas(canvas);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            holder.unlockCanvasAndPost(canvas);
        }
    }

    private void drawCanvas(Canvas canvas) {
        // 在 canvas 上繪制需要的圖形
    }
}

到此這篇關於Android SurfaceView基礎用法詳解的文章就介紹到這瞭,更多相關Android SurfaceView基礎內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: