diff --git a/shell/platform/android/io/flutter/embedding/android/FlutterFragmentActivity.java b/shell/platform/android/io/flutter/embedding/android/FlutterFragmentActivity.java index f21fadf0fa300..b796c8ed43e48 100644 --- a/shell/platform/android/io/flutter/embedding/android/FlutterFragmentActivity.java +++ b/shell/platform/android/io/flutter/embedding/android/FlutterFragmentActivity.java @@ -390,6 +390,12 @@ FlutterFragment retrieveExistingFlutterFragmentIfPossible() { * FlutterFragment} is created and added. */ private void ensureFlutterFragmentCreated() { + if (flutterFragment == null) { + // If both activity and fragment have been destroyed, the activity restore may have + // already recreated a new instance of the fragment again via the FragmentActivity.onCreate + // and the FragmentManager. + flutterFragment = retrieveExistingFlutterFragmentIfPossible(); + } if (flutterFragment == null) { // No FlutterFragment exists yet. This must be the initial Activity creation. We will create // and add a new FlutterFragment to this Activity. @@ -602,7 +608,7 @@ public FlutterEngine provideFlutterEngine(@NonNull Context context) { */ @Override public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { - if (flutterFragment.isFlutterEngineInjected()) { + if (flutterFragment != null && flutterFragment.isFlutterEngineInjected()) { // If the FlutterEngine was explicitly built and injected into this FlutterActivity, the // builder should explicitly decide whether to automatically register plugins via the // FlutterEngine's construction parameter or via the AndroidManifest metadata. diff --git a/shell/platform/android/test/io/flutter/embedding/android/FlutterFragmentActivityTest.java b/shell/platform/android/test/io/flutter/embedding/android/FlutterFragmentActivityTest.java index 1b14a4a6e4639..fe63994e56f07 100644 --- a/shell/platform/android/test/io/flutter/embedding/android/FlutterFragmentActivityTest.java +++ b/shell/platform/android/test/io/flutter/embedding/android/FlutterFragmentActivityTest.java @@ -199,6 +199,26 @@ public void itRetrievesExistingFlutterFragmentWhenRecreated() { assertEquals(0, activity.numberOfEnginesCreated); } + @Test + public void itHandlesNewFragmentRecreationDuringRestoreWhenActivityIsRecreated() { + FlutterFragmentActivityWithProvidedEngine activity = + spy(Robolectric.buildActivity(FlutterFragmentActivityWithProvidedEngine.class).get()); + + FlutterFragment fragment = mock(FlutterFragment.class); + // Similar to the above case, except here, it's not just the activity that was destroyed and + // could have its fragment restored in the fragment manager. Here, both activity and fragment + // are destroyed. And the fragment manager recreated the fragment on activity recreate. + when(activity.retrieveExistingFlutterFragmentIfPossible()).thenReturn(null, fragment); + + FlutterEngine engine = mock(FlutterEngine.class); + when(fragment.getFlutterEngine()).thenReturn(engine); + + activity.onCreate(null); + // The framework would have recreated a new fragment but the fragment activity wouldn't have + // created a new one again. + assertEquals(0, activity.numberOfEnginesCreated); + } + static class FlutterFragmentActivityWithProvidedEngine extends FlutterFragmentActivity { int numberOfEnginesCreated = 0;