From afe3420efc2ec1cdcece7d55db4e15314655afdb Mon Sep 17 00:00:00 2001 From: Christian Bernier Date: Fri, 10 Jul 2026 10:59:37 -0400 Subject: [PATCH] fix: remove NavView fragment via the FragmentManager it is attached to NavViewManager.onDropViewInstance removed the map/navigation fragment through reactContext.getCurrentActivity()'s support FragmentManager. When the view is dropped while getCurrentActivity() points at a different Activity than the one hosting the fragment (e.g. after Activity recreation), that FragmentManager never hosted the fragment and androidx throws: IllegalStateException: Cannot remove Fragment attached to a different FragmentManager Use the fragment's own getParentFragmentManager() for the remove transaction instead, and guard against the FragmentManager being already destroyed mid-teardown. This also no longer skips cleanup (leaking the fragmentMap entry) when getCurrentActivity() is null. Co-Authored-By: Claude Fable 5 --- .../android/react/navsdk/NavViewManager.java | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/android/src/main/java/com/google/android/react/navsdk/NavViewManager.java b/android/src/main/java/com/google/android/react/navsdk/NavViewManager.java index d2bc700..7b42bfd 100644 --- a/android/src/main/java/com/google/android/react/navsdk/NavViewManager.java +++ b/android/src/main/java/com/google/android/react/navsdk/NavViewManager.java @@ -304,18 +304,24 @@ public void onDropViewInstance(@NonNull FrameLayout view) { controllerSink.clear(); } - FragmentActivity activity = (FragmentActivity) reactContext.getCurrentActivity(); - if (activity == null) return; - WeakReference weakReference = fragmentMap.remove(viewId); if (weakReference != null) { IMapViewFragment fragment = weakReference.get(); if (fragment != null && fragment.isAdded()) { - activity - .getSupportFragmentManager() - .beginTransaction() - .remove((Fragment) fragment) - .commitNowAllowingStateLoss(); + // Remove via the FragmentManager the fragment is actually attached to. + // reactContext.getCurrentActivity() can be a different Activity than the one hosting the + // fragment (e.g. after Activity recreation), in which case removing through its + // FragmentManager throws "Cannot remove Fragment attached to a different FragmentManager". + try { + ((Fragment) fragment) + .getParentFragmentManager() + .beginTransaction() + .remove((Fragment) fragment) + .commitNowAllowingStateLoss(); + } catch (IllegalStateException e) { + // FragmentManager already destroyed mid-teardown; the fragment is torn down with its + // host Activity anyway. + } } } }