Skip to main content

用於渲染至 Surface 的 Android 插件新 API

在 Android 嵌入 API 中新增了一個名為 SurfaceProducer 的新 API, 可不透明地處理插件的 `Surface` 創建與管理。 對於 Impeller,建議使用此 API。

摘要

#

Flutter 的 Android 嵌入層引入了一個新的 API,SurfaceProducer, 允許插件渲染至 Surface,而無需管理其底層實作。 使用舊有 createSurfaceTexture API 的插件,在下個穩定版發佈後仍可與 Impeller 搭配運作, 但建議遷移至新 API。

背景

#

Android 的 SurfaceTextureSurface 的底層實作, 其使用 OpenGLES 紋理作為底層儲存區。

舉例來說,某個插件可能會顯示來自 camera 插件的畫面:

Flowchart

在較新版本的 Android API(>= 29)中,Android 引入了一個 與後端無關的 HardwareBuffer,這也正好是 Flutter 嘗試使用 Vulkan 渲染器的最低版本。為此,Android 嵌入 API 需要更新,以支援更通用的 Surface 創建 API,不再依賴於 OpenGLES。

遷移指南

#

如果你正在使用舊的 createSurfaceTexture API,建議遷移至 新的 createSurfaceProducer API。新 API 更具彈性,允許 Flutter 引擎 不透明地為當前平台與 API 等級選擇最佳實作。

  1. 請改為建立 SurfaceProducer,而非 SurfaceTextureEntry

    java
    TextureRegistry.SurfaceTextureEntry entry = textureRegistry.createSurfaceTexture();
    TextureRegistry.SurfaceProducer producer = textureRegistry.createSurfaceProducer();
    
  2. 請改為在 SurfaceProducer 上呼叫 getSurface(),而不是建立 new Surface(...)

    java
    Surface surface = new Surface(entry.surfaceTexture());
    Surface surface = producer.getSurface();
    

為了在應用程式於背景暫停時節省記憶體,Android 和 Flutter 可能 會在畫面不再可見時銷毀 surface(表面)。為了確保當應用程式回到前景時能正確重新建立 surface,你應該使用提供的 setCallback 方法來監聽 surface 生命週期事件:

java
surfaceProducer.setCallback(
   new TextureRegistry.SurfaceProducer.Callback() {
      @Override
      public void onSurfaceAvailable() {
         // Do surface initialization here, and draw the current frame.
      }

      @Override
      public void onSurfaceDestroyed() {
         // Do surface cleanup here, and stop drawing frames.
      }
   }
);

可以在 PR 6989 中找到一個完整使用此新 API 的範例,該範例針對 video_player_android 插件。

關於相機預覽的注意事項

#

如果你的插件實作了相機預覽功能,遷移時可能還需要修正預覽畫面的旋轉。這是因為由 SurfaceProducer 所產生的 Surface 可能不包含 Android 函式庫自動正確旋轉預覽所需的轉換資訊。

為了修正旋轉,你需要根據相機感測器方向與裝置方向,依照下列公式對預覽畫面進行旋轉:

rotation = (sensorOrientationDegrees - deviceOrientationDegrees * sign + 360) % 360

其中 deviceOrientationDegrees 代表逆時針旋轉的角度,sign 則為 1 表示前置相機,-1 表示後置相機。

要計算這個旋轉角度時:

要套用這個旋轉,你可以使用 RotatedBox 元件 (Widget)。

如需此計算的更多資訊,請參考 Android orientation calculation documentation。若需完整修正範例,請參考 this camera_android_camerax PR

時程

#

導入版本:3.22

穩定版:3.24

在即將推出的穩定版 3.27 中,onSurfaceCreated 將被棄用,並新增 onSurfaceAvailablehandlesCropAndRotation

參考資料

#

API 文件:

相關議題:

相關 PR:

  • PR 51061,在這裡我們於 engine 測試中測試了新 API。
  • PR 6456,在這裡我們將 video_player 插件遷移至新 API。
  • PR 6461,在這裡我們將 camera_android 插件遷移至新 API。
  • PR 6989,在這裡我們於 video_player_android 插件中新增了完整的新 API 使用範例。