概述

#

Flutter 的 Android 嵌入器引入了一個新 API:SurfaceProducer。該 API 允許外掛渲染到 Surface,而無需管理底層實現。使用舊版 createSurfaceTexture API 的外掛在下一個穩定版本釋出後仍可與 Impeller 相容,但建議遷移到新 API。

背景

#

Android 的 SurfaceTextureSurface 的一種底層實現,它使用 OpenGLES 紋理作為後端儲存。

例如,外掛可能會顯示來自相機外掛的幀

Flowchart

在較新版本的 Android API(>= 29)中,Android 引入了一種與後端無關的 HardwareBuffer,這恰好與 Flutter 將嘗試使用的 Vulkan 渲染器的最低版本相吻合。Android 嵌入 API 需要更新以支援更通用的 Surface 建立 API,該 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 *可能*會在表面不再可見時銷燬該表面。為確保在應用程式恢復時重新建立表面,您應該使用提供的 setCallback 方法來監聽表面生命週期事件。

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.
      }
   }
);

使用此新 API 的完整示例可以在 video_player_android 外掛的 PR 6989 中找到。

關於相機預覽的說明

#

如果您的外掛實現了相機預覽,您的遷移可能還需要修復預覽的旋轉。這是因為 SurfaceProducer 生成的 Surface 可能不包含 Android 庫自動正確旋轉預覽所需的那種轉換資訊。

為了糾正旋轉,您需要根據相機感測器方向和裝置方向,按照以下公式旋轉預覽:

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

其中 deviceOrientationDegrees 是逆時針方向的角度,sign 對於前置攝像頭為 1,對於後置攝像頭為 -1。

要計算此旋轉,請執行以下操作:

要應用此旋轉,您可以使用 RotatedBox 小部件。

有關此計算的更多資訊,請參閱 Android 方向計算文件。有關進行此修復的完整示例,請參閱 camera_android_camerax PR

時間線

#

已於版本:3.22 落地

在穩定版中:3.24

在即將釋出的穩定版 3.27 中,onSurfaceCreated 已棄用,並添加了 onSurfaceAvailablehandlesCropAndRotation

參考資料

#

API 文件

相關問題

相關 PR

  • PR 51061 中,我們在引擎測試中測試了新 API。
  • PR 6456 中,我們遷移了 video_player 外掛以使用新 API。
  • PR 6461 中,我們遷移了 camera_android 外掛以使用新 API。
  • PR 6989 中,我們在 video_player_android 外掛中添加了使用新 API 的完整示例。