diff --git a/shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java b/shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java index 8dec2a05052dc..f0cd24adea675 100644 --- a/shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java +++ b/shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java @@ -131,11 +131,11 @@ final class SurfaceTextureRegistryEntry implements TextureRegistry.SurfaceTextur new SurfaceTexture.OnFrameAvailableListener() { @Override public void onFrameAvailable(@NonNull SurfaceTexture texture) { - if (released) { - // Even though we make sure to unregister the callback before releasing, as of Android - // O - // SurfaceTexture has a data race when accessing the callback, so the callback may - // still be called by a stale reference after released==true and mNativeView==null. + if (released || !flutterJNI.isAttached()) { + // Even though we make sure to unregister the callback before releasing, as of + // Android O, SurfaceTexture has a data race when accessing the callback, so the + // callback may still be called by a stale reference after released==true and + // mNativeView==null. return; } markTextureFrameAvailable(id); diff --git a/shell/platform/android/test/io/flutter/embedding/engine/renderer/FlutterRendererTest.java b/shell/platform/android/test/io/flutter/embedding/engine/renderer/FlutterRendererTest.java index 4b3884085b93b..185ed43fa08c2 100644 --- a/shell/platform/android/test/io/flutter/embedding/engine/renderer/FlutterRendererTest.java +++ b/shell/platform/android/test/io/flutter/embedding/engine/renderer/FlutterRendererTest.java @@ -97,4 +97,23 @@ public void itStopsRenderingToSurfaceWhenRequested() { // Verify behavior under test. verify(fakeFlutterJNI, times(1)).onSurfaceDestroyed(); } + + @Test + public void itStopsSurfaceTextureCallbackWhenDetached() { + // Setup the test. + FlutterRenderer flutterRenderer = new FlutterRenderer(fakeFlutterJNI); + + fakeFlutterJNI.detachFromNativeAndReleaseResources(); + + FlutterRenderer.SurfaceTextureRegistryEntry entry = + (FlutterRenderer.SurfaceTextureRegistryEntry) flutterRenderer.createSurfaceTexture(); + + flutterRenderer.startRenderingToSurface(fakeSurface); + + // Execute the behavior under test. + flutterRenderer.stopRenderingToSurface(); + + // Verify behavior under test. + verify(fakeFlutterJNI, times(0)).markTextureFrameAvailable(eq(entry.id())); + } }