用于渲染到表面的 Android 插件的新 API
摘要
#Flutter 的 Android 嵌入器引入了一个新的 API,SurfaceProducer
,它允许插件渲染到 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 级别选择最佳实现。
不要创建
SurfaceTextureEntry
,而是创建一个SurfaceProducer
:javaTextureRegistry.SurfaceTextureEntry entry = textureRegistry.createSurfaceTexture(); TextureRegistry.SurfaceProducer producer = textureRegistry.createSurfaceProducer();
不要创建
new Surface(...)
,而是在SurfaceProducer
上调用getSurface()
:javaSurface surface = new Surface(entry.surfaceTexture()); Surface surface = producer.getSurface();
为了在应用程序在后台暂停时节省内存,Android 和 Flutter 可能会 在表面不再可见时销毁它。为了确保在应用程序恢复时重新创建表面,您应该使用提供的 setCallback
方法来监听表面生命周期事件:
surfaceProducer.setCallback(
new TextureRegistry.SurfaceProducer.Callback() {
@Override
public void onSurfaceAvailable() {
// 在此处进行表面初始化,并绘制当前帧。
}
@Override
public void onSurfaceDestroyed() {
// 在此处进行表面清理,并停止绘制帧。
}
}
);
可以在 video_player_android
插件的 PR 6989 中找到使用此新 API 的完整示例。
关于相机预览的说明
#如果您的插件实现了相机预览,您的迁移可能还需要修复该预览的旋转。这是因为 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:
- PR 51061,我们在引擎测试中测试了新的 API。
- PR 6456,我们迁移了
video_player
插件以使用新的 API。 - PR 6461,我们迁移了
camera_android
插件以使用新的 API。 - PR 6989,我们在
video_player_android
插件中添加了使用新 API 的完整示例。
除非另有说明,否则本网站上的文档反映的是 Flutter 的最新稳定版本。页面最后更新于 2025-01-30。 查看源代码 或 报告问题。