diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.java index cb97a34a523..75aacd7e0d5 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.java @@ -67,7 +67,6 @@ import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Set; -import java.util.concurrent.Callable; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicInteger; @@ -201,12 +200,7 @@ public class ReactHostImpl implements ReactHost { */ @Override public TaskInterface start() { - if (ReactFeatureFlags.enableBridgelessArchitectureNewCreateReloadDestroy) { - return Task.call(this::newGetOrCreateStartTask, mBGExecutor) - .continueWithTask(Task::getResult); - } - - return Task.call(this::oldGetOrCreateStartTask, mBGExecutor).continueWithTask(Task::getResult); + return Task.call(this::newGetOrCreateStartTask, mBGExecutor).continueWithTask(Task::getResult); } /** Initialize and run a React Native surface in a background without mounting real views. */ @@ -441,36 +435,32 @@ public class ReactHostImpl implements ReactHost { @Override public TaskInterface reload(String reason) { final String method = "reload()"; - if (ReactFeatureFlags.enableBridgelessArchitectureNewCreateReloadDestroy) { - return Task.call( - () -> { - Task reloadTask = null; - if (mDestroyTask != null) { - log(method, "Waiting for destroy to finish, before reloading React Native."); - reloadTask = - mDestroyTask - .continueWithTask(task -> newGetOrCreateReloadTask(reason), mBGExecutor) - .makeVoid(); - } else { - reloadTask = newGetOrCreateReloadTask(reason).makeVoid(); - } + return Task.call( + () -> { + Task reloadTask = null; + if (mDestroyTask != null) { + log(method, "Waiting for destroy to finish, before reloading React Native."); + reloadTask = + mDestroyTask + .continueWithTask(task -> newGetOrCreateReloadTask(reason), mBGExecutor) + .makeVoid(); + } else { + reloadTask = newGetOrCreateReloadTask(reason).makeVoid(); + } - return reloadTask.continueWithTask( - task -> { - if (task.isFaulted()) { - mReactHostDelegate.handleInstanceException(task.getError()); - return newGetOrCreateDestroyTask("Reload failed", task.getError()); - } + return reloadTask.continueWithTask( + task -> { + if (task.isFaulted()) { + mReactHostDelegate.handleInstanceException(task.getError()); + return newGetOrCreateDestroyTask("Reload failed", task.getError()); + } - return task; - }, - mBGExecutor); - }, - mBGExecutor) - .continueWithTask(Task::getResult); - } - - return oldReload(reason); + return task; + }, + mBGExecutor); + }, + mBGExecutor) + .continueWithTask(Task::getResult); } /** @@ -486,24 +476,19 @@ public class ReactHostImpl implements ReactHost { @Override public TaskInterface destroy(String reason, @Nullable Exception ex) { final String method = "destroy()"; - if (ReactFeatureFlags.enableBridgelessArchitectureNewCreateReloadDestroy) { - return Task.call( - () -> { - if (mReloadTask != null) { - log( - method, - "Reloading React Native. Waiting for reload to finish before destroying React Native."); - return mReloadTask.continueWithTask( - task -> newGetOrCreateDestroyTask(reason, ex), mBGExecutor); - } - return newGetOrCreateDestroyTask(reason, ex); - }, - mBGExecutor) - .continueWithTask(Task::getResult); - } - - oldDestroy(reason, ex); - return Task.forResult(nullsafeFIXME(null, "Empty Destroy Task")); + return Task.call( + () -> { + if (mReloadTask != null) { + log( + method, + "Reloading React Native. Waiting for reload to finish before destroying React Native."); + return mReloadTask.continueWithTask( + task -> newGetOrCreateDestroyTask(reason, ex), mBGExecutor); + } + return newGetOrCreateDestroyTask(reason, ex); + }, + mBGExecutor) + .continueWithTask(Task::getResult); } private MemoryPressureListener createMemoryPressureListener(ReactInstance reactInstance) { @@ -720,30 +705,6 @@ public class ReactHostImpl implements ReactHost { @ThreadConfined("ReactHost") private @Nullable Task mStartTask = null; - @ThreadConfined("ReactHost") - private Task oldGetOrCreateStartTask() { - if (mStartTask == null) { - final String method = "oldGetOrCreateStartTask()"; - log(method, "Schedule"); - mStartTask = - getOrCreateReactInstance() - .continueWithTask( - task -> { - if (task.isFaulted()) { - destroy( - "oldGetOrCreateStartTask() failure: " + task.getError().getMessage(), - task.getError()); - mReactHostDelegate.handleInstanceException(task.getError()); - } - - return task; - }, - mBGExecutor) - .makeVoid(); - } - return mStartTask; - } - @ThreadConfined("ReactHost") private Task newGetOrCreateStartTask() { if (mStartTask == null) { @@ -857,12 +818,8 @@ public class ReactHostImpl implements ReactHost { * destroying, will wait until destroy is finished, before creating. */ private Task getOrCreateReactInstance() { - if (ReactFeatureFlags.enableBridgelessArchitectureNewCreateReloadDestroy) { - return Task.call(this::waitThenCallNewGetOrCreateReactInstanceTask, mBGExecutor) - .continueWithTask(Task::getResult); - } - - return oldGetOrCreateReactInstanceTask(); + return Task.call(this::waitThenCallNewGetOrCreateReactInstanceTask, mBGExecutor) + .continueWithTask(Task::getResult); } @ThreadConfined("ReactHost") @@ -1021,87 +978,6 @@ public class ReactHostImpl implements ReactHost { }); } - private Task oldGetOrCreateReactInstanceTask() { - final String method = "oldGetOrCreateReactInstanceTask()"; - log(method); - - return mReactInstanceTaskRef.getOrCreate( - () -> { - log(method, "Start"); - ReactMarker.logMarker( - ReactMarkerConstants.REACT_BRIDGELESS_LOADING_START, BRIDGELESS_MARKER_INSTANCE_KEY); - - final BridgelessReactContext reactContext = getOrCreateReactContext(); - final DevSupportManager devSupportManager = getDevSupportManager(); - reactContext.setJSExceptionHandler(devSupportManager); - - return getJsBundleLoader() - .onSuccess( - task -> { - final JSBundleLoader bundleLoader = task.getResult(); - log(method, "Creating ReactInstance"); - final ReactInstance instance = - new ReactInstance( - reactContext, - mReactHostDelegate, - mComponentFactory, - devSupportManager, - mQueueThreadExceptionHandler, - mReactJsExceptionHandler, - mUseDevSupport); - - if (ReactFeatureFlags - .unstable_bridgelessArchitectureMemoryPressureHackyBoltsFix) { - mMemoryPressureListener = createMemoryPressureListener(instance); - } - mMemoryPressureRouter.addMemoryPressureListener(mMemoryPressureListener); - - log(method, "Loading JS Bundle"); - instance.loadJSBundle(bundleLoader); - - log( - method, - "Calling DevSupportManagerBase.onNewReactContextCreated(reactContext)"); - devSupportManager.onNewReactContextCreated(reactContext); - reactContext.runOnJSQueueThread( - () -> { - // Executing on the JS thread to ensurethat we're done - // loading the JS bundle. - // TODO T76081936 Move this if we switchto a sync RTE - ReactMarker.logMarker( - ReactMarkerConstants.REACT_BRIDGELESS_LOADING_END, - BRIDGELESS_MARKER_INSTANCE_KEY); - }); - return instance; - }, - mBGExecutor) - .onSuccess( - task -> { - /* - Call ReactContext.onHostResume() only when already in the resumed state which - aligns with the bridge https://fburl.com/diffusion/2qhxmudv. - */ - mReactLifecycleStateManager.resumeReactContextIfHostResumed( - reactContext, getCurrentActivity()); - - ReactInstanceEventListener[] listeners = - new ReactInstanceEventListener[mReactInstanceEventListeners.size()]; - final ReactInstanceEventListener[] finalListeners = - mReactInstanceEventListeners.toArray(listeners); - - log(method, "Executing ReactInstanceEventListeners"); - for (ReactInstanceEventListener listener : finalListeners) { - if (listener != null) { - listener.onReactContextInitialized(reactContext); - } - } - - return task.getResult(); - }, - mUIExecutor); - }); - } - private Task getJsBundleLoader() { final String method = "getJSBundleLoader()"; log(method); @@ -1604,141 +1480,6 @@ public class ReactHostImpl implements ReactHost { return mDestroyTask; } - /** Destroy and recreate the ReactInstance and context. */ - private Task oldReload(String reason) { - final String method = "oldReload()"; - log(method); - - // Log how React Native is destroyed - // TODO(T136397487): Remove after Venice is shipped to 100% - raiseSoftException(method, reason); - - synchronized (mReactInstanceTaskRef) { - mMemoryPressureRouter.removeMemoryPressureListener(mMemoryPressureListener); - oldDestroyReactInstanceAndContext(method, reason); - - return callAfterGetOrCreateReactInstance( - method, - reactInstance -> { - // Restart any attached surfaces - log(method, "Restarting Surfaces"); - synchronized (mAttachedSurfaces) { - for (ReactSurfaceImpl surface : mAttachedSurfaces) { - reactInstance.startSurface(surface); - } - } - }); - } - } - - /** Destroy the specified instance and context. */ - private void oldDestroy(String reason, @Nullable Exception ex) { - final String method = "oldDestroy()"; - log(method); - - // Log how React Native is destroyed - // TODO(T136397487): Remove after Venice is shipped to 100% - raiseSoftException(method, reason, ex); - - synchronized (mReactInstanceTaskRef) { - // Prevent re-destroy when ReactInstance has been reset already, which could happen when - // calling destroy multiple times on the same thread - ReactInstance reactInstance = mReactInstanceTaskRef.get().getResult(); - if (reactInstance == null) { - return; - } - - // Retain a reference to current ReactContext before de-referenced by mReactContextRef - final ReactContext reactContext = getCurrentReactContext(); - - if (reactContext != null) { - mMemoryPressureRouter.destroy(reactContext); - } - - oldDestroyReactInstanceAndContext(method, reason); - - // Remove all attached surfaces - log(method, "Clearing attached surfaces"); - synchronized (mAttachedSurfaces) { - mAttachedSurfaces.clear(); - } - - Task.call( - (Callable) - () -> { - moveToHostDestroy(reactContext); - return null; - }, - mUIExecutor); - } - } - - private void oldDestroyReactInstanceAndContext(final String callingMethod, final String reason) { - final String method = "oldDestroyReactInstanceAndContext(" + callingMethod + ")"; - log(method); - - synchronized (mReactInstanceTaskRef) { - Task task = mReactInstanceTaskRef.getAndReset(); - if (!task.isFaulted() && !task.isCancelled()) { - final ReactInstance instance = task.getResult(); - - // Noop on redundant calls to destroyReactInstance() - if (instance == null) { - log(method, "ReactInstance is null"); - return; - } - - /* - * The surfaces should be stopped before the instance destroy. - * Calling stop directly on instance ensures we keep the list of attached surfaces for restart. - */ - log(method, "Stopping surfaces"); - synchronized (mAttachedSurfaces) { - for (ReactSurfaceImpl surface : mAttachedSurfaces) { - instance.stopSurface(surface); - surface.clear(); - } - } - - ReactContext reactContext = getCurrentReactContext(); - - // Reset the ReactContext inside the DevSupportManager - if (reactContext != null) { - log(method, "DevSupportManager.onReactInstanceDestroyed()"); - getDevSupportManager().onReactInstanceDestroyed(reactContext); - log(method, "Destroy ReactContext"); - mBridgelessReactContextRef.reset(); - } - - mBGExecutor.execute( - () -> { - // instance.destroy() is time consuming and is confined to ReactHost thread. - log(method, "Destroy ReactInstance"); - instance.destroy(); - - // Re-enable preloads - log(method, "Resetting Preload task ref"); - mStartTask = null; - }); - } else { - raiseSoftException( - method, - ("Not cleaning up ReactInstance: task.isFaulted() = " - + task.isFaulted() - + ", task.isCancelled() = " - + task.isCancelled()) - + ". Reason: " - + reason); - - mBGExecutor.execute( - () -> { - log(method, "Resetting Preload task ref"); - mStartTask = null; - }); - } - } - } - @Nullable @Override public JSEngineResolutionAlgorithm getJsEngineResolutionAlgorithm() {