From 1fbf5ef0b86e083cce34381243b36ca7b052341f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rulong=20Chen=EF=BC=88=E9=99=88=E6=B1=9D=E9=BE=99=EF=BC=89?= Date: Thu, 20 Jan 2022 09:30:02 +0800 Subject: [PATCH] Remove the unused FlutterImageView from FlutterView to avoid leaks (#30873) --- .../flutter/embedding/android/FlutterView.java | 4 ++++ .../embedding/android/FlutterViewTest.java | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/shell/platform/android/io/flutter/embedding/android/FlutterView.java b/shell/platform/android/io/flutter/embedding/android/FlutterView.java index 6e858204d9dd4..b172d2aa11f41 100644 --- a/shell/platform/android/io/flutter/embedding/android/FlutterView.java +++ b/shell/platform/android/io/flutter/embedding/android/FlutterView.java @@ -1226,6 +1226,10 @@ public void detachFromFlutterEngine() { if (flutterImageView != null) { flutterImageView.closeImageReader(); + // Remove the FlutterImageView that was previously added by {@code convertToImageView} to + // avoid leaks when this FlutterView is reused later in the scenario where multiple + // FlutterActivitiy/FlutterFragment share one engine. + removeView(flutterImageView); flutterImageView = null; } previousRenderSurface = null; diff --git a/shell/platform/android/test/io/flutter/embedding/android/FlutterViewTest.java b/shell/platform/android/test/io/flutter/embedding/android/FlutterViewTest.java index 7a99f5fe04cdf..ee3bad454be9a 100644 --- a/shell/platform/android/test/io/flutter/embedding/android/FlutterViewTest.java +++ b/shell/platform/android/test/io/flutter/embedding/android/FlutterViewTest.java @@ -135,6 +135,24 @@ public void detachFromFlutterEngine_revertImageView() { assertFalse(flutterView.renderSurface instanceof FlutterImageView); } + @Test + public void detachFromFlutterEngine_removeImageView() { + FlutterView flutterView = new FlutterView(RuntimeEnvironment.application); + FlutterEngine flutterEngine = + spy(new FlutterEngine(RuntimeEnvironment.application, mockFlutterLoader, mockFlutterJni)); + + flutterView.attachToFlutterEngine(flutterEngine); + flutterView.convertToImageView(); + assertEquals(flutterView.getChildCount(), 2); + View view = flutterView.getChildAt(1); + assertTrue(view instanceof FlutterImageView); + + flutterView.detachFromFlutterEngine(); + assertEquals(flutterView.getChildCount(), 1); + view = flutterView.getChildAt(0); + assertFalse(view instanceof FlutterImageView); + } + @Test public void detachFromFlutterEngine_closesImageView() { FlutterEngine flutterEngine =