Flutter 3.41 is live! Check out theFlutter 3.41 blog post!
New APIs for Android plugins that render to a Surface
Adds a new API, SurfaceProducer, to the Android embedding API, which opaquely handles the creation and management of a `Surface` for plugins. For Impeller, use of this API is recommended.
These breaking change docs are accurate, as of the release under which they are published. Over time, the workarounds described here might become inaccurate. We don't, in general, keep these breaking change docs up to date as of each release.
Thebreaking change index file lists the docs created for each release.
Summary
# The Android embedder for Flutter introduces a new API,SurfaceProducer, which allows plugins to render to aSurface without needing to manage what the backing implementation is. Plugins using the oldercreateSurfaceTexture API will continue to work withImpeller after thenext stable release, but are recommended to migrate to the new API.
Background
# An AndroidSurfaceTexture is a backing implementation for aSurface that uses anOpenGLES texture as the backing store.
For example, a plugin might display frames from acamera plugin:
In newer versions of the Android API (>= 29), Android introduced a backend-agnosticHardwareBuffer, which coincides with the minimum version that Flutter will attempt to use theVulkan renderer. The Android embedding API needed to be updated to support a more genericSurface creation API that doesn't rely on OpenGLES.
Migration guide
# If you are using the oldercreateSurfaceTexture API, you should migrate to the newcreateSurfaceProducer API. The new API is more flexible and allows the Flutter engine to opaquely pick the best implementation for the current platform and API level.
Instead of creating a
SurfaceTextureEntry, create aSurfaceProducer:javaTextureRegistry.SurfaceTextureEntryentry=textureRegistry.createSurfaceTexture();TextureRegistry.SurfaceProducerproducer=textureRegistry.createSurfaceProducer();Instead of creating a
new Surface(...), callgetSurface()on theSurfaceProducer:javaSurfacesurface=newSurface(entry.surfaceTexture());Surfacesurface=producer.getSurface();
In order to conserve memory when the application is suspended in the background, Android and Fluttermay destroy a surface when it is no longer visible. To ensure that the surface is recreated when the application is resumed, you should use the providedsetCallback method to listen to surface lifecycle events:
surfaceProducer.setCallback(newTextureRegistry.SurfaceProducer.Callback(){@OverridepublicvoidonSurfaceAvailable(){// Do surface initialization here, and draw the current frame.}@OverridepublicvoidonSurfaceDestroyed(){// Do surface cleanup here, and stop drawing frames.}}); A full example of using this new API can be found inPR 6989 for thevideo_player_android plugin.
In early versions of this API, the callback was namedonSurfaceCreated, and was invoked even if the original surface was not destroyed. This has been fixed in the latest (pending 3.27) version of the API.
Note on camera previews
# If your plugin implements a camera preview, your migration might also require fixing the rotation of that preview. This is becauseSurfaces produced by theSurfaceProducer might not contain the transformation information that Android libraries need to correctly rotate the preview automatically.
In order to correct the rotation, you need to rotate the preview with respect to the camera sensor orientation and the device orientation according to the equation:
rotation = (sensorOrientationDegrees - deviceOrientationDegrees * sign + 360) % 360 wheredeviceOrientationDegrees is counterclockwise degrees andsign is 1 for front-facing cameras and -1 for back-facing cameras.
To calculate this rotation,
- Use
SurfaceProducer.handlesCropAndRotationto check if the underlyingSurfacehandles rotation (iffalse, you may need to handle the rotation). - Retrieve the sensor orientation degrees by retrieving the value of
CameraCharacteristics.SENSOR_ORIENTATION. - Retrieve the device orientation degrees in one of the ways that theAndroid orientation calculation documentation details.
To apply this rotation, you can use aRotatedBox widget.
For more information on this calculation, check out theAndroid orientation calculation documentation. For a full example of making this fix, check outthiscamera_android_camerax PR.
Timeline
#Landed in version: 3.22
This feature landed in theprevious version of the SDK but was non-functional; plugins that migrate to this API should set3.24 as a minimum version constraint.
In stable release: 3.24
In the upcoming stable release, 3.27,onSurfaceCreated is deprecated, andonSurfaceAvailable andhandlesCropAndRotation are added.
References
#API documentation:
Relevant issues:
Relevant PRs:
Unless stated otherwise, the documentation on this site reflects Flutter 3.38.6. Page last updated on 2025-10-28.View source orreport an issue.