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

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

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

前言

一、什么是SurfaceView ?

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

1.1 SurfaceView 使用示例

SurfaceView 的常見用法通常是在視頻播放、相機(jī)預(yù)覽或?qū)崟r(shí)圖形渲染等場景中。以下是一個(gè)簡單的 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)建時(shí)調(diào)用,可以在此開始渲染
        Surface surface = holder.getSurface();
    }
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        // 當(dāng) Surface 大小或格式改變時(shí)調(diào)用
        // 更新渲染內(nèi)容或調(diào)整顯示內(nèi)容
    }
    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        // 在 Surface 銷毀時(shí)調(diào)用
        // 停止渲染操作并釋放資源
    }
}

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

1.2 SurfaceView 源碼概述

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1.5 SurfaceView 渲染機(jī)制

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

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

SurfaceView 在后臺(tái)線程中會(huì)使用 SurfaceHolder.lockCanvas() 獲取 Canvas 對(duì)象,然后進(jìn)行圖形繪制。繪制完成后,通過 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 用于顯示一個(gè)內(nèi)容的紋理。它和 SurfaceView 的功能類似,但實(shí)現(xiàn)方式有所不同。
TextureView 允許將 OpenGL 渲染的內(nèi)容、視頻幀或其他圖像直接作用在 UI 線程上,并且能夠在任何地方進(jìn)行動(dòng)畫、旋轉(zhuǎn)或縮放,而不僅限于一個(gè)固定的 Surface。
相較于 SurfaceView,TextureView 在靈活性和控制方面有更多的優(yōu)勢。

2.1 TextureView 使用示例

下面是一個(gè)簡單的 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)建時(shí),初始化 Surface
                Surface newSurface = new Surface(surface);
                // 可以在這里執(zhí)行渲染操作
            }
            @Override
            public void onSurfaceChanged(SurfaceTexture surface, int width, int height) {
                // Surface 改變大小時(shí)
            }
            @Override
            public void onSurfaceDestroyed(SurfaceTexture surface) {
                // Surface 銷毀時(shí)
            }
            @Override
            public void onSurfaceUpdated(SurfaceTexture surface) {
                // 每次 Surface 更新時(shí)調(diào)用
            }
        });
    }
}

2.2 TextureView 源碼概述

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

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

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

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

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

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

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

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

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

private void init() {
    // 創(chuàng)建 SurfaceTexture 對(duì)象
    mSurfaceTexture = new SurfaceTexture(false);
    // 創(chuàng)建 Surface 對(duì)象
    mSurface = new Surface(mSurfaceTexture);
    // 設(shè)置視圖的緩沖區(qū)和其他默認(rèn)參數(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 實(shí)例
mSurface = new Surface(mSurfaceTexture);     // 使用 

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

2.4 SurfaceTextureListener 回調(diào)

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

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

2.5 TextureView渲染流程

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

初始化 SurfaceTexture 和 Surface:

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

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

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

3.SurfaceTexture 更新:

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

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

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

三、SurfaceView和TextureView區(qū)別

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

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

相關(guān)文章

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

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

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

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

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

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

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

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

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

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

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

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

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

    25個(gè)實(shí)用酷炫的Android開源UI框架

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

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

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

    Android 顯示GIF圖片實(shí)例詳解

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

    android webView截圖的4種方法

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

最新評(píng)論