欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android的SurfaceView和TextureView介紹及使用示例

 更新時間:2024年12月12日 14:50:20   作者:找藉口是失敗者的習慣  
SurfaceView 是一種用于直接將圖形繪制到屏幕的Android組件,下面給大家分享SurfaceView使用示例,它展示了如何在 Android 應(yīng)用中創(chuàng)建并使用,感興趣的朋友一起看看吧

前言

一、什么是SurfaceView ?

SurfaceView 是一種用于直接將圖形繪制到屏幕的Android組件。與常規(guī)的 View 不同,SurfaceView 通過使用一個獨立的 Surface 來進行渲染,它不直接依賴于主 UI 線程,而是利用單獨的硬件加速的線程進行渲染。

1.1 SurfaceView 使用示例

SurfaceView 的常見用法通常是在視頻播放、相機預覽或?qū)崟r圖形渲染等場景中。以下是一個簡單的 SurfaceView 使用示例,它展示了如何在 Android 應(yīng)用中創(chuàng)建并使用 SurfaceView:

布局 XML 文件 (res/layout/activity_main.xml)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <android.view.SurfaceView
        android:id="@+id/surfaceView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>
import android.os.Bundle;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback {
    private SurfaceView surfaceView;
    private SurfaceHolder surfaceHolder;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        surfaceView = findViewById(R.id.surfaceView);
        surfaceHolder = surfaceView.getHolder();
        surfaceHolder.addCallback(this);  // 注冊回調(diào)
    }
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        // 在 Surface 創(chuàng)建時調(diào)用,可以在此開始渲染
        Surface surface = holder.getSurface();
    }
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        // 當 Surface 大小或格式改變時調(diào)用
        // 更新渲染內(nèi)容或調(diào)整顯示內(nèi)容
    }
    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        // 在 Surface 銷毀時調(diào)用
        // 停止渲染操作并釋放資源
    }
}

在上述示例中,我們首先在布局中定義了一個 SurfaceView,然后通過 surfaceView.getHolder() 獲取 SurfaceHolder,并注冊了 SurfaceHolder.Callback 接口來處理 Surface 的生命周期。

1.2 SurfaceView 源碼概述

SurfaceView 主要用于處理需要高效、實時渲染的場景,例如視頻播放、游戲渲染、相機預覽等。它的渲染操作由后臺線程執(zhí)行,避免了與主 UI 線程的競爭,提升了性能。

主要類及源碼文件
SurfaceView 類位于 frameworks/base/core/java/android/view/SurfaceView.java。
通過 getHolder() 獲取與 SurfaceView 關(guān)聯(lián)的 SurfaceHolder。
SurfaceHolder 是一個接口,通過它可以獲取與 SurfaceView 關(guān)聯(lián)的 Surface 對象并進行渲染。

1.3 SurfaceView 的構(gòu)造與初始化

SurfaceView 在初始化時,首先通過 getHolder() 獲取 SurfaceHolder,然后注冊回調(diào)接口來處理 Surface 的生命周期。具體代碼如下:

public SurfaceView(Context context) {
    super(context);
    mSurfaceHolder = getHolder(); // 獲取 SurfaceHolder
    mSurfaceHolder.addCallback(this); // 注冊回調(diào)
}

在此過程中,getHolder() 返回一個 SurfaceHolder 對象,該對象用于管理與 SurfaceView 關(guān)聯(lián)的 Surface。SurfaceHolder.Callback 回調(diào)接口的實現(xiàn)幫助我們在 Surface 創(chuàng)建、改變和銷毀時執(zhí)行相應(yīng)的操作。

1.4 SurfaceHolder.Callback 回調(diào)接口

SurfaceHolder.Callback 是一個關(guān)鍵接口,SurfaceView 使用它來處理與 Surface 相關(guān)的生命周期事件。它包括三個主要回調(diào)方法:

surfaceCreated(SurfaceHolder holder)
surfaceCreated() 方法在 Surface 被創(chuàng)建時調(diào)用。此時,SurfaceView 可以開始渲染圖形內(nèi)容。

@Override
public void surfaceCreated(SurfaceHolder holder) {
    // 此時 Surface 創(chuàng)建成功,可以開始渲染
    Surface surface = holder.getSurface();
    // 進行圖形渲染,通常啟動渲染線程
}

surfaceChanged(SurfaceHolder holder, int format, int width, int height)
當 Surface 的格式或尺寸發(fā)生變化時,surfaceChanged() 會被調(diào)用。此時,應(yīng)用程序可以根據(jù)新的尺寸調(diào)整渲染內(nèi)容。

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    // 處理 Surface 格式或尺寸變化
}

surfaceDestroyed(SurfaceHolder holder)
當 Surface 被銷毀時,surfaceDestroyed() 會被調(diào)用。此時,應(yīng)用程序應(yīng)停止渲染操作并釋放資源。

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    // 停止渲染線程并釋放資源
}

1.5 SurfaceView 渲染機制

SurfaceView 的渲染由后臺線程處理,渲染過程包括鎖定 Canvas、進行繪制并提交結(jié)果。

后臺線程Surface
SurfaceView 的渲染并不在主 UI 線程中進行,而是通過后臺線程來完成的。這是為了避免 UI 線程的阻塞,確保 UI 能夠流暢運行。

SurfaceView 在后臺線程中會使用 SurfaceHolder.lockCanvas() 獲取 Canvas 對象,然后進行圖形繪制。繪制完成后,通過 SurfaceHolder.unlockCanvasAndPost() 提交更新。

public void render(Surface surface) {
    Canvas canvas = null;
    try {
        canvas = holder.lockCanvas(null); // 鎖定 Canvas
        if (canvas != null) {
            // 在 Canvas 上繪制圖形內(nèi)容
            canvas.drawColor(Color.BLACK);  // 清屏
            // 繪制其他內(nèi)容
        }
    } finally {
        if (canvas != null) {
            holder.unlockCanvasAndPost(canvas); // 提交繪制結(jié)果
        }
    }
}

二、什么是TextureView?

TextureView 用于顯示一個內(nèi)容的紋理。它和 SurfaceView 的功能類似,但實現(xiàn)方式有所不同。
TextureView 允許將 OpenGL 渲染的內(nèi)容、視頻幀或其他圖像直接作用在 UI 線程上,并且能夠在任何地方進行動畫、旋轉(zhuǎn)或縮放,而不僅限于一個固定的 Surface。
相較于 SurfaceView,TextureView 在靈活性和控制方面有更多的優(yōu)勢。

2.1 TextureView 使用示例

下面是一個簡單的 TextureView 使用示例。

public class MyActivity extends AppCompatActivity {
    private TextureView textureView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textureView = findViewById(R.id.textureView);
        textureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
            @Override
            public void onSurfaceCreated(SurfaceTexture surface, int width, int height) {
                // Surface 創(chuàng)建時,初始化 Surface
                Surface newSurface = new Surface(surface);
                // 可以在這里執(zhí)行渲染操作
            }
            @Override
            public void onSurfaceChanged(SurfaceTexture surface, int width, int height) {
                // Surface 改變大小時
            }
            @Override
            public void onSurfaceDestroyed(SurfaceTexture surface) {
                // Surface 銷毀時
            }
            @Override
            public void onSurfaceUpdated(SurfaceTexture surface) {
                // 每次 Surface 更新時調(diào)用
            }
        });
    }
}

2.2 TextureView 源碼概述

以下是 TextureView 源碼概述的核心內(nèi)容,詳細分析其結(jié)構(gòu)和工作原理。

1、關(guān)鍵類和接口
TextureView 類:TextureView 是整個視圖系統(tǒng)的核心,它繼承自 View 類。它的主要職責是通過 SurfaceTexture 渲染圖像內(nèi)容,并通過 Surface 顯示。

SurfaceTexture:SurfaceTexture 是與 OpenGL 渲染綁定的對象,用于顯示圖像流。它為 TextureView 提供了一個接口,通過它可以將渲染內(nèi)容傳輸?shù)?SurfaceView 或 TextureView。

Surface:Surface 是 Android 用于圖形渲染的基本容器。SurfaceTexture 通過 Surface 輸出圖形數(shù)據(jù),TextureView 通過此 Surface 顯示內(nèi)容。

SurfaceTextureListener 接口:該接口提供了與 SurfaceTexture 生命周期相關(guān)的回調(diào)方法,開發(fā)者可以通過實現(xiàn)該接口來響應(yīng) Surface 創(chuàng)建、更新和銷毀的事件。

2.3 TextureView 的構(gòu)造與初始化

1、構(gòu)造函數(shù)
TextureView 提供了多個構(gòu)造函數(shù),可以通過不同的方式初始化對象。最常見的構(gòu)造函數(shù)是:

public TextureView(Context context) {
    super(context);
    init();
}

在構(gòu)造函數(shù)中,TextureView 被初始化并配置了所需的 SurfaceTexture。通過調(diào)用 init() 方法,SurfaceTexture 和 Surface 將被創(chuàng)建,并為后續(xù)的圖像渲染做好準備。

private void init() {
    // 創(chuàng)建 SurfaceTexture 對象
    mSurfaceTexture = new SurfaceTexture(false);
    // 創(chuàng)建 Surface 對象
    mSurface = new Surface(mSurfaceTexture);
    // 設(shè)置視圖的緩沖區(qū)和其他默認參數(shù)
    setOpaque(true);  // 設(shè)置是否為不透明
    mSurfaceTextureListener = null;
}

2. SurfaceTexture 和 Surface 的創(chuàng)建
TextureView 的核心是通過 SurfaceTexture 來獲取渲染的數(shù)據(jù)流,并通過 Surface 來顯示這些圖像內(nèi)容。創(chuàng)建 SurfaceTexture 和 Surface 的代碼如下:

mSurfaceTexture = new SurfaceTexture(false);  // 創(chuàng)建 SurfaceTexture 實例
mSurface = new Surface(mSurfaceTexture);     // 使用 

SurfaceTexture 創(chuàng)建 Surface
SurfaceTexture 是渲染內(nèi)容的承載者,它接收渲染引擎(如 OpenGL)的輸出,并將其傳遞給 Surface。
Surface 是渲染結(jié)果的顯示容器,TextureView 通過該 Surface 來顯示圖像。
SurfaceTexture 的參數(shù) false 表示它是一個非透明的紋理。在大多數(shù)情況下,使用非透明紋理可以獲得更好的渲染性能。

2.4 SurfaceTextureListener 回調(diào)

TextureView 還提供了一個接口 SurfaceTextureListener,用于接收 SurfaceTexture 生命周期的回調(diào)事件。這個回調(diào)接口包含了多個方法,可以在 SurfaceTexture 創(chuàng)建、更新或銷毀時進行處理。

  • onSurfaceCreated(SurfaceTexture surface, int width, int height):當 SurfaceTexture 創(chuàng)建時調(diào)用。此時可以開始渲染內(nèi)容。
  • onSurfaceChanged(SurfaceTexture surface, int width, int height):當 SurfaceTexture 尺寸發(fā)生變化時調(diào)用??梢杂脕砀落秩緝?nèi)容或調(diào)整顯示尺寸。
  • onSurfaceDestroyed(SurfaceTexture surface):當 SurfaceTexture 銷毀時調(diào)用,可以在此時釋放資源。
  • onSurfaceUpdated(SurfaceTexture surface):每次 SurfaceTexture 更新時調(diào)用,用于通知渲染更新。

2.5 TextureView渲染流程

TextureView 的渲染流程主要依賴于 SurfaceTexture 和 Surface 來將圖像渲染到屏幕上。以下是該渲染流程的關(guān)鍵步驟:

初始化 SurfaceTexture 和 Surface:

TextureView 在初始化時創(chuàng)建一個 SurfaceTexture 對象,該對象用于接收圖形數(shù)據(jù)。
然后將 SurfaceTexture 封裝為 Surface,Surface 用于顯示圖像內(nèi)容。

圖像數(shù)據(jù)傳遞到 SurfaceTexture:

圖形引擎(如 OpenGL)將渲染結(jié)果傳遞給 SurfaceTexture,這些數(shù)據(jù)會被存儲在 SurfaceTexture 中。

3.SurfaceTexture 更新:

一旦 SurfaceTexture 中的圖像數(shù)據(jù)更新,TextureView 會收到通知,并準備將新圖像內(nèi)容顯示出來。
SurfaceTexture 會將最新的圖像數(shù)據(jù)傳遞給關(guān)聯(lián)的 Surface。

顯示圖像內(nèi)容:

Surface 在 TextureView 上渲染和顯示圖像內(nèi)容。此時,TextureView 會將圖像數(shù)據(jù)呈現(xiàn)到屏幕上。

三、SurfaceView和TextureView區(qū)別

特性SurfaceViewTextureView
渲染方式渲染內(nèi)容直接通過硬件層輸出,不經(jīng)過 UI 層,繞過屏幕緩沖區(qū)通過 SurfaceTexture 渲染內(nèi)容,經(jīng)過 UI 層(即視圖層)顯示
性能高性能,適合要求低延遲、高幀率的應(yīng)用,如視頻播放、實時游戲等性能相對較低,適用于對 UI 層交互、動畫有要求的應(yīng)用
渲染效率渲染在獨立的硬件層,減少 UI 線程負擔,圖形處理獨立渲染經(jīng)過 UI 層,渲染性能相對較低,可能會受到 UI 層操作影響
硬件加速支持直接使用硬件加速,不依賴 UI 線程,適合高效圖形渲染使用硬件加速,但圖形渲染受 UI 線程限制
變換與動畫支持不支持內(nèi)建的圖像變換,若需動畫或變換需要依賴外部圖形庫如 OpenGL支持矩陣變換(旋轉(zhuǎn)、縮放、平移等),支持視圖動畫和動態(tài)效果
視圖層級與嵌套渲染層與 UI 層分離,不能與其他視圖進行直接交互或嵌套渲染內(nèi)容在 UI 層,可以和其他視圖層級交互、嵌套和變換
生命周期管理通過 SurfaceHolder.Callback 回調(diào)接口管理 Surface 的生命周期通過 SurfaceTextureListener 回調(diào)接口管理 SurfaceTexture 生命周期
適用場景適用于視頻播放、實時游戲渲染等對性能要求高的應(yīng)用適用于動態(tài)變換、動畫和需要與 UI 層交互的場景(如視頻展示、圖像旋轉(zhuǎn))
支持的 UI 操作不支持直接與 UI 層進行交互(例如點擊、動畫、視圖更新等)支持與 UI 層的交互,支持視圖動畫(例如 setTransform() 變換)
硬件渲染與UI渲染渲染直接在硬件層進行,不依賴 UI 線程渲染通過 UI 層進行,UI 線程參與渲染處理,可能有性能開銷
透明背景支持不直接支持透明背景支持透明背景,適合需要透明或部分透明效果的應(yīng)用
支持多層顯示支持多層顯示,但通常是通過 Surface 進行不同圖層顯示支持多圖層顯示,允許將多個 TextureView 嵌套并渲染不同內(nèi)容
顯示內(nèi)容更新渲染內(nèi)容更新較為簡單,依賴 lockCanvas、unlockCanvasAndPost顯示內(nèi)容更新通過 SurfaceTexture 更新,內(nèi)容刷新通過 updateTexImage()
硬件解碼視頻非常適合硬件解碼視頻,視頻數(shù)據(jù)直接渲染到硬件層不如 SurfaceView 高效,視頻數(shù)據(jù)需要通過 SurfaceTexture 渲染
UI 線程影響不會受到 UI 線程影響,獨立的渲染線程渲染依賴 UI 線程,可能會影響 UI 線程的流暢性,特別是在高負荷情況下
可嵌入到布局中不可以直接與其他視圖一起進行布局可以像普通視圖一樣嵌入布局,支持與其他視圖交互和變換
旋轉(zhuǎn)與縮放不支持內(nèi)建旋轉(zhuǎn)、縮放等變換,需使用外部圖形庫支持內(nèi)建旋轉(zhuǎn)、縮放和其他變換,支持多種變換方式
API 支持支持大部分 Android 設(shè)備,并且對硬件解碼支持較好支持大部分 Android 設(shè)備,適合需要在視圖層做渲染處理的場景
渲染線程在獨立線程中進行渲染,UI 線程與渲染分離渲染在 UI 線程中進行,UI 操作與渲染共用一個線程

到此這篇關(guān)于Android的SurfaceView和TextureView介紹的文章就介紹到這了,更多相關(guān)Android SurfaceView和TextureView內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Android中okhttp3.4.1+retrofit2.1.0實現(xiàn)離線緩存

    Android中okhttp3.4.1+retrofit2.1.0實現(xiàn)離線緩存

    這篇文章主要介紹了Android中okhttp3.4.1結(jié)合retrofit2.1.0實現(xiàn)離線緩存,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • android studio使用SQLiteOpenHelper()建立數(shù)據(jù)庫的方法

    android studio使用SQLiteOpenHelper()建立數(shù)據(jù)庫的方法

    這篇文章主要介紹了android studio使用SQLiteOpenHelper()建立數(shù)據(jù)庫的方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-03-03
  • Android?WebView基礎(chǔ)舉例詳解

    Android?WebView基礎(chǔ)舉例詳解

    在Android開發(fā)中Webview是一個重要的組件,它允許我們在原生應(yīng)用中內(nèi)嵌網(wǎng)頁內(nèi)容,提供混合式應(yīng)用的用戶體驗,這篇文章主要給大家介紹了關(guān)于Android?WebView基礎(chǔ)的相關(guān)資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2024-07-07
  • Android關(guān)于BottomNavigationView使用指南

    Android關(guān)于BottomNavigationView使用指南

    本文主要介紹了Android關(guān)于BottomNavigationView使用指南,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • Android中獲得正在運行的程序和系統(tǒng)服務(wù)的方法

    Android中獲得正在運行的程序和系統(tǒng)服務(wù)的方法

    這篇文章主要介紹了Android中獲得正在運行的程序和系統(tǒng)服務(wù)的方法,分別是對ActivityManager.RunningAppProcessInfo類和ActivityManager.RunningServiceInfo類的使用,需要的朋友可以參考下
    2016-02-02
  • Android編程設(shè)計模式之中介者模式詳解

    Android編程設(shè)計模式之中介者模式詳解

    這篇文章主要介紹了Android編程設(shè)計模式之中介者模式,結(jié)合實例形式詳細分析了Android中介者模式的概念、原理、使用場景、用法及相關(guān)操作注意事項,需要的朋友可以參考下
    2017-12-12
  • 25個實用酷炫的Android開源UI框架

    25個實用酷炫的Android開源UI框架

    本文為大家分享了25個實用酷炫的Android開源UI框架,靈活運用這些UI框架可在日常工作中節(jié)省不少時間
    2018-04-04
  • Android Studio中導入module的方法(簡單版)

    Android Studio中導入module的方法(簡單版)

    這篇文章主要介紹了AndroidStudio中導入module的方法,本文是一篇簡易版的教程,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2018-01-01
  • Android 顯示GIF圖片實例詳解

    Android 顯示GIF圖片實例詳解

    這篇文章主要介紹了Android 顯示GIF圖片實例詳解的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • android webView截圖的4種方法

    android webView截圖的4種方法

    這篇文章主要為大家詳細介紹了android webView截圖的4種方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-05-05

最新評論