支持渲染到 Surface 的 Android 插件新 API
概述
#Flutter 的 Android 嵌入器引入了一个新 API:SurfaceProducer
。该 API 允许插件渲染到 Surface
,而无需管理底层实现。使用旧版 createSurfaceTexture
API 的插件在下一个稳定版本发布后仍可与 Impeller 兼容,但建议迁移到新 API。
背景
#Android 的 SurfaceTexture
是 Surface
的一种底层实现,它使用 OpenGLES 纹理作为后端存储。
例如,插件可能会显示来自相机插件的帧
在较新版本的 Android API(>= 29)中,Android 引入了一种与后端无关的 HardwareBuffer
,这恰好与 Flutter 将尝试使用的 Vulkan 渲染器的最低版本相吻合。Android 嵌入 API 需要更新以支持更通用的 Surface
创建 API,该 API 不依赖于 OpenGLES。
迁移指南
#如果您使用的是旧版 createSurfaceTexture
API,则应迁移到新的 createSurfaceProducer
API。新 API 更具灵活性,允许 Flutter 引擎不透明地选择当前平台和 API 级别的最佳实现。
创建
SurfaceProducer
,而不是创建SurfaceTextureEntry
javaTextureRegistry.SurfaceTextureEntry entry = textureRegistry.createSurfaceTexture(); TextureRegistry.SurfaceProducer producer = textureRegistry.createSurfaceProducer();
调用
SurfaceProducer
上的getSurface()
,而不是创建new Surface(...)
javaSurface surface = new Surface(entry.surfaceTexture()); Surface surface = producer.getSurface();
为了在应用程序后台暂停时节省内存,Android 和 Flutter *可能*会在表面不再可见时销毁该表面。为确保在应用程序恢复时重新创建表面,您应该使用提供的 setCallback
方法来监听表面生命周期事件。
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。
要计算此旋转,请执行以下操作:
- 使用
SurfaceProducer.handlesCropAndRotation
检查底层Surface
是否处理旋转(如果为false
,则您可能需要处理旋转)。 - 通过检索
CameraCharacteristics.SENSOR_ORIENTATION
的值来获取传感器方向(度数)。 - 通过 Android 方向计算文档中所述的一种方法来获取设备方向(度数)。
要应用此旋转,您可以使用 RotatedBox
小部件。
有关此计算的更多信息,请参阅 Android 方向计算文档。有关进行此修复的完整示例,请参阅 此 camera_android_camerax
PR。
时间线
#已于版本:3.22 落地
在稳定版中:3.24
在即将发布的稳定版 3.27 中,onSurfaceCreated
已弃用,并添加了 onSurfaceAvailable
和 handlesCropAndRotation
。
参考资料
#API 文档
相关问题
相关 PR