Android Surface詳解

一、Surface的基本概念

Surface是Android系統中一個重要的原語,它是一塊屏幕的抽象表示。它提供了一個支持繪製、更改尺寸、透明度、格式和管理SurfaceView的生命周期的接口。在Android應用程序中,Surface通常表示一個可以渲染、處理用戶輸入、與其他SurfaceView進行組合的視圖元素。

在不同的場景下,Surface可以有不同的實現方式:SurfaceView、TextureView、GLSurfaceView等等。SurfaceView是其中應用最為廣泛的一種實現方式,因為在面向用戶的應用程序中,通過SurfaceView可以提供流暢的UI交互和動畫效果。

二、SurfaceView的使用

SurfaceView是Android系統提供的一種底層視圖,它可以用於自定義繪製以及更高效地渲染大量視圖。

下面是一個簡單的SurfaceView實現代碼:

public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback {

    private Thread drawThread;
    private volatile boolean running = false;

    public MySurfaceView(Context context, AttributeSet attrs) {
        super(context, attrs);
        getHolder().addCallback(this);
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        running = true;
        drawThread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (running) {
                    draw();
                }
            }
        });
        drawThread.start();
    }

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

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        running = false;
        try {
            drawThread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private void draw() {
        SurfaceHolder holder = getHolder();
        Canvas canvas = holder.lockCanvas();
        if (canvas != null) {
            // 繪製
            holder.unlockCanvasAndPost(canvas);
        }
    }
}

在該實現中,我們重寫了SurfaceView的三個生命周期方法,分別是surfaceCreated、surfaceChanged和surfaceDestroyed。在surfaceCreated中,我們創建了一個繪製線程,在循環中不斷地調用draw()方法來進行繪製工作。在surfaceDestroyed中,我們停止了繪製線程,調用join()方法等待其結束。

三、SurfaceView的局限性

儘管SurfaceView提供了一個強大的繪製框架,但是在實際開發中,我們也要考慮到其局限性。在特定的場景下,SurfaceView可能會出現一些問題,例如:卡頓、閃爍、裂屏等等。

為了解決這些問題,我們可以採用一些優化手段,例如:

四、TextureView的使用

TextureView是Android系統提供的一種基於硬件加速的視圖,它可以在不同Surface之間進行無縫切換,並且支持疊加和混合。在一些高級應用程序中,如果需要同時顯示多個Surface,我們可以選擇使用TextureView實現。

下面是一個簡單的TextureView實現代碼:

public class MyTextureView extends TextureView implements TextureView.SurfaceTextureListener {

    private Thread drawThread;
    private volatile boolean running = false;
    private SurfaceTexture surfaceTexture;

    public MyTextureView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setSurfaceTextureListener(this);
    }

    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) {
        running = true;
        this.surfaceTexture = surfaceTexture;
        drawThread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (running) {
                    draw();
                }
            }
        });
        drawThread.start();
    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int width, int height) {
        // TODO: Implement onSurfaceTextureSizeChanged()
    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
        running = false;
        try {
            drawThread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return true;
    }

    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
        // TODO: Implement onSurfaceTextureUpdated()
    }

    private void draw() {
        if (surfaceTexture == null) {
            return;
        }
        Canvas canvas = lockCanvas();
        if (canvas != null) {
            // 繪製
            unlockCanvasAndPost(canvas);
        }
    }
}

在該實現中,我們實現了TextureView.SurfaceTextureListener,用於監聽SurfaceTexture的生命周期事件。在onSurfaceTextureAvailable中,我們創建了一個繪製線程,在循環中不斷地調用draw()方法來進行繪製工作。在onSurfaceTextureDestroyed中,我們停止了繪製線程,調用join()方法等待其結束。

五、GLSurfaceView的使用

GLSurfaceView是Android系統提供的一種可與OpenGL ES結合使用的視圖,它可以對3D場景進行實時渲染。在需要實現動態圖像和高級圖形效果時,我們可以選擇使用GLSurfaceView實現。

下面是一個簡單的GLSurfaceView實現代碼:

public class MyGLSurfaceView extends GLSurfaceView implements Renderer {

    private FloatBuffer vertexBuffer;
    private float[] vertices = {0f, 1f, -1f, -1f, 1f, -1f};

    public MyGLSurfaceView(Context context) {
        super(context);
        setEGLContextClientVersion(2);
        setRenderer(this);
    }

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        // 初始化
        ByteBuffer bb = ByteBuffer.allocateDirect(vertices.length * 4);
        bb.order(ByteOrder.nativeOrder());
        vertexBuffer = bb.asFloatBuffer();
        vertexBuffer.put(vertices);
        vertexBuffer.position(0);
        gl.glClearColor(0f, 0f, 0f, 0f);
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        // TODO: Implement onSurfaceChanged()
    }

    @Override
    public void onDrawFrame(GL10 gl) {
        // 渲染
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
        gl.glColor4f(0f, 1f, 0f, 1f);
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertexBuffer);
        gl.glDrawArrays(GL10.GL_TRIANGLES, 0, vertices.length / 2);
        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
    }
}

在該實現中,我們重寫了GLSurfaceView的三個生命周期方法,分別是onSurfaceCreated、onSurfaceChanged和onDrawFrame。在onSurfaceCreated中,我們初始化了一些OpenGL ES相關的屬性和參數。在onDrawFrame中,我們對3D場景進行渲染操作,具體內容可以在OpenGL ES相關文檔中找到。

原創文章,作者:KRTND,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/371617.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
KRTND的頭像KRTND
上一篇 2025-04-23 18:08
下一篇 2025-04-23 18:08

相關推薦

  • Android ViewPager和ScrollView滑動衝突問題

    Android開發中,ViewPager和ScrollView是兩個常用的控件。但是當它們同時使用時,可能會發生滑動衝突的問題。本文將從多個方面介紹解決Android ViewPa…

    編程 2025-04-28
  • Android如何點擊其他區域收起軟鍵盤

    在Android應用中,當輸入框獲取焦點彈出軟鍵盤後,我們希望能夠點擊其他區域使軟鍵盤消失,以提升用戶體驗。本篇文章將說明如何實現這一功能。 一、獲取焦點並顯示軟鍵盤 在Andro…

    編程 2025-04-28
  • Android Studio HUD 實現指南

    本文將會以實例來詳細闡述如何在 Android Studio 中使用 HUD 功能實現菊花等待指示器的效果。 一、引入依賴庫 首先,我們需要在 build.gradle 文件中引入…

    編程 2025-04-27
  • Android和Vue3混合開發方案

    本文將介紹如何將Android和Vue3結合起來進行混合開發,以及其中的優勢和注意事項。 一、環境搭建 在進行混合開發之前,需要搭建好相應的開發環境。首先需要安裝 Android …

    編程 2025-04-27
  • Android Java Utils 可以如何提高你的開發效率

    Android Java Utils 是一款提供了一系列方便實用的工具類的 Java 庫,可以幫助開發者更加高效地進行 Android 開發,提高開發效率。本文將從以下幾個方面對 …

    編程 2025-04-27
  • Linux sync詳解

    一、sync概述 sync是Linux中一個非常重要的命令,它可以將文件系統緩存中的內容,強制寫入磁盤中。在執行sync之前,所有的文件系統更新將不會立即寫入磁盤,而是先緩存在內存…

    編程 2025-04-25
  • 神經網絡代碼詳解

    神經網絡作為一種人工智能技術,被廣泛應用於語音識別、圖像識別、自然語言處理等領域。而神經網絡的模型編寫,離不開代碼。本文將從多個方面詳細闡述神經網絡模型編寫的代碼技術。 一、神經網…

    編程 2025-04-25
  • git config user.name的詳解

    一、為什麼要使用git config user.name? git是一個非常流行的分布式版本控制系統,很多程序員都會用到它。在使用git commit提交代碼時,需要記錄commi…

    編程 2025-04-25
  • 詳解eclipse設置

    一、安裝與基礎設置 1、下載eclipse並進行安裝。 2、打開eclipse,選擇對應的工作空間路徑。 File -> Switch Workspace -> [選擇…

    編程 2025-04-25
  • C語言貪吃蛇詳解

    一、數據結構和算法 C語言貪吃蛇主要運用了以下數據結構和算法: 1. 鏈表 typedef struct body { int x; int y; struct body *nex…

    編程 2025-04-25

發表回復

登錄後才能評論