From 23fa14b94c98efcf62e29f873c13f784730e930b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hanno=20J=2E=20G=C3=B6decke?= Date: Fri, 10 Oct 2025 12:06:12 +0200 Subject: [PATCH] fix(android): `onHostPause` crashes with multiple active activities fix(android): crash `onHostPause` with multiple active activities --- .../facebook/react/runtime/ReactHostImpl.kt | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.kt index c7e0c339c9029d..179000d6961050 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.kt @@ -66,6 +66,7 @@ import com.facebook.react.uimanager.events.BlackHoleEventDispatcher import com.facebook.react.uimanager.events.EventDispatcher import com.facebook.react.views.imagehelper.ResourceDrawableIdHelper import java.lang.ref.WeakReference +import java.util.WeakHashMap import java.util.concurrent.CopyOnWriteArrayList import java.util.concurrent.Executor import java.util.concurrent.Executors @@ -137,6 +138,7 @@ public class ReactHostImpl( private val reactLifecycleStateManager = ReactLifecycleStateManager(stateTracker) private var memoryPressureListener: MemoryPressureListener? = null private var defaultHardwareBackBtnHandler: DefaultHardwareBackBtnHandler? = null + private val activeActivitiesMap = WeakHashMap(); private val reactInstanceEventListeners: MutableList = CopyOnWriteArrayList() @@ -241,6 +243,10 @@ public class ReactHostImpl( override fun onHostResume(activity: Activity?) { stateTracker.enterState("onHostResume(activity)") + if (activity != null) { + activeActivitiesMap[activity] = true + } + currentActivity = activity maybeEnableDevSupport(true) @@ -259,25 +265,17 @@ public class ReactHostImpl( val method = "onHostPause(activity)" stateTracker.enterState(method) - val currentActivity = this.currentActivity - if (currentActivity != null) { - val isSameActivity = activity === currentActivity - if (!isSameActivity) { - val currentActivityClass = currentActivity.javaClass.simpleName - val activityClass = if (activity == null) "null" else activity.javaClass.simpleName - val isNotSameActivityMessage = - "Pausing an activity that is not the current activity, this is incorrect! Current activity: $currentActivityClass Paused activity: $activityClass" - if (ReactNativeFeatureFlags.skipActivityIdentityAssertionOnHostPause()) { - FLog.w(TAG, method, isNotSameActivityMessage) - } else { - Assertions.assertCondition(isSameActivity, isNotSameActivityMessage) - } + if (activity != null) { + activeActivitiesMap.remove(activity) + if (activeActivitiesMap.size > 0) { + FLog.w(TAG, "Called $method by activity $activity but there are still active activities, not pausing yet.") + return } } maybeEnableDevSupport(false) defaultHardwareBackBtnHandler = null - reactLifecycleStateManager.moveToOnHostPause(currentReactContext, currentActivity) + reactLifecycleStateManager.moveToOnHostPause(currentReactContext, activity) } /** To be called when the host activity is paused. */