Skip to content

Fatal Exception: PlatformViewWrapper.draw after 3.24.1 update #155018

@alex-kobozev-talabat

Description

@alex-kobozev-talabat

Description

We are experiencing a crash in our Flutter Android application after 3.24.1 update. The crash occurs sporadically on various screens, with a majority happening on screens that contain Google Maps, but other screens can also be affected. The issue seems to occur on different Android devices and versions, with plenty of free RAM available. Unfortunately, we have been unable to reproduce this issue locally, despite attempting to simulate extreme memory and resource conditions.

The stack trace consistently shows the exception java.lang.IllegalStateException: Surface has already been released. So far, we have observed ~800 crashes with an average of 1 crash per unique user, and we are unable to pinpoint any specific pattern.

          Fatal Exception: java.lang.IllegalStateException: Surface has already been released.
       at android.view.Surface.checkNotReleasedLocked(Surface.java:787)
       at android.view.Surface.lockHardwareCanvas(Surface.java:537)
       at io.flutter.plugin.platform.PlatformViewWrapper.draw(PlatformViewWrapper.java:169)
       at android.view.View.updateDisplayListIfDirty(View.java:24036)
       at android.view.View.draw(View.java:24907)
       at android.view.ViewGroup.drawChild(ViewGroup.java:4780)
       at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4538)
       at android.view.View.updateDisplayListIfDirty(View.java:24022)
       at android.view.View.draw(View.java:24907)
       at android.view.ViewGroup.drawChild(ViewGroup.java:4780)
       at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4538)
       at android.view.View.updateDisplayListIfDirty(View.java:24022)
       at android.view.View.draw(View.java:24907)
       at android.view.ViewGroup.drawChild(ViewGroup.java:4780)
       at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4538)
       at android.view.View.updateDisplayListIfDirty(View.java:24022)
       at android.view.View.draw(View.java:24907)
       at android.view.ViewGroup.drawChild(ViewGroup.java:4780)
       at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4538)
       at android.view.View.updateDisplayListIfDirty(View.java:24022)
       at android.view.View.draw(View.java:24907)
       at android.view.ViewGroup.drawChild(ViewGroup.java:4780)
       at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4538)
       at com.android.internal.policy.DecorView.dispatchDraw(DecorView.java:1179)
       at android.view.View.draw(View.java:25180)
       at com.android.internal.policy.DecorView.draw(DecorView.java:1161)
       at android.view.View.updateDisplayListIfDirty(View.java:24036)
       at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:768)
       at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:774)
       at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:872)
       at android.view.ViewRootImpl.draw(ViewRootImpl.java:6051)
       at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:5706)
       at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:4795)
       at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:3288)
       at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:11344)
       at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1689)
       at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1698)
       at android.view.Choreographer.doCallbacks(Choreographer.java:1153)
       at android.view.Choreographer.doFrame(Choreographer.java:1079)
       at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1646)
       at android.os.Handler.handleCallback(Handler.java:958)
       at android.os.Handler.dispatchMessage(Handler.java:99)
       at android.os.Looper.loopOnce(Looper.java:230)
       at android.os.Looper.loop(Looper.java:319)
       at android.app.ActivityThread.main(ActivityThread.java:8919)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:578)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)
        

Frequency

~800 crashes recorded across various devices and users.
1 crash per unique user on average.

Environment

Flutter Version: 3.24.1
Dart Version: 3.5.1
Android OS Versions: Multiple versions, including Android 10-15.
Devices: Various models from multiple manufacturers (e.g., Samsung, Google Pixel, Xiaomi, etc.).
Google Maps: google_maps_flutter: 2.6.0

Expected results

The app should function without crashing, regardless of surface release status.

Actual results

The app crashes with a java.lang.IllegalStateException: Surface has already been released error. The exact cause of the surface being released prematurely is unclear, and no specific pattern has been identified.

Code sample

https://github.com/alex-kobozev-talabat/flutter_surface_example

but it uses reflection to access the surface. I understand there is no way for the surface to be accesses like that in real life, and of course we don't use it in our app like that, but this example can simulate the case when the surface can be released somehow by the Android system (when app is on background or any other case). Anyways the stacktrace is the same we have in crashlytics

Metadata

Metadata

Assignees

No one assigned

    Labels

    a: platform-viewsEmbedding Android/iOS views in Flutter appsa: productionIssues experienced in live production appsc: crashStack traces logged to the consoleneeds repro infoAutomated crash report whose cause isn't yet knownplatform-androidAndroid applications specificallyr: fixedIssue is closed as already fixed in a newer versionteam-androidOwned by Android platform teamtriaged-androidTriaged by Android platform team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions