From ea48fd24ea41a5ede1004a36fb91675a3f31694b Mon Sep 17 00:00:00 2001 From: David Vacca Date: Fri, 30 Jun 2023 14:57:39 -0700 Subject: [PATCH] Resorting methods in ReactHost class (#38043) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/38043 Resorting methods in ReactHost class, this class in very long and to make it easy to read and analyze I'm sorting methods as public -> package -> private no changes of behavior are happening here bypass-github-export-checks changelog: [internal] internal Reviewed By: cortinico Differential Revision: D46773622 fbshipit-source-id: 4e2867930dc84ef410569532e8a195e491a6a553 --- .../facebook/react/bridgeless/ReactHost.java | 387 +++++++++--------- 1 file changed, 193 insertions(+), 194 deletions(-) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridgeless/ReactHost.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridgeless/ReactHost.java index 35f671c4f64..8f28651c94d 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridgeless/ReactHost.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridgeless/ReactHost.java @@ -88,6 +88,7 @@ public class ReactHost implements ReactHostInterface { private static final boolean DEV = ReactBuildConfig.DEBUG; private static final String TAG = "ReactHost"; private static final int BRIDGELESS_MARKER_INSTANCE_KEY = 1; + private static final AtomicInteger mCounter = new AtomicInteger(0); private final Context mContext; private final ReactHostDelegate mReactHostDelegate; @@ -99,7 +100,6 @@ public class ReactHost implements ReactHostInterface { private final QueueThreadExceptionHandler mQueueThreadExceptionHandler; private final Set mAttachedSurfaces = Collections.synchronizedSet(new HashSet<>()); private final MemoryPressureRouter mMemoryPressureRouter; - private MemoryPressureListener mMemoryPressureListener; private final boolean mAllowPackagerServerAccess; private final boolean mUseDevSupport; private final Collection mReactInstanceEventListeners = @@ -115,15 +115,14 @@ public class ReactHost implements ReactHostInterface { new BridgelessAtomicRef<>(); private final AtomicReference mActivity = new AtomicReference<>(); - private @Nullable DefaultHardwareBackBtnHandler mDefaultHardwareBackBtnHandler; private final BridgelessReactStateTracker mBridgelessReactStateTracker = new BridgelessReactStateTracker(DEV); private final ReactLifecycleStateManager mReactLifecycleStateManager = new ReactLifecycleStateManager(mBridgelessReactStateTracker); - - private static final AtomicInteger mCounter = new AtomicInteger(0); private final int mId = mCounter.getAndIncrement(); private @Nullable JSEngineResolutionAlgorithm mJSEngineResolutionAlgorithm = null; + private MemoryPressureListener mMemoryPressureListener; + private @Nullable DefaultHardwareBackBtnHandler mDefaultHardwareBackBtnHandler; public ReactHost( Context context, @@ -176,19 +175,6 @@ public class ReactHost implements ReactHostInterface { mUseDevSupport = useDevSupport; } - private MemoryPressureListener createMemoryPressureListener(ReactInstance reactInstance) { - WeakReference weakReactInstance = new WeakReference<>(reactInstance); - return (level) -> { - mBGExecutor.execute( - () -> { - @Nullable ReactInstance strongReactInstance = weakReactInstance.get(); - if (strongReactInstance != null) { - strongReactInstance.handleMemoryPressure(level); - } - }); - }; - } - @Override public LifecycleState getLifecycleState() { return mReactLifecycleStateManager.getLifecycleState(); @@ -211,66 +197,6 @@ public class ReactHost implements ReactHostInterface { return oldStart(); } - @ThreadConfined("ReactHost") - private @Nullable Task mStartTask = null; - - private Task oldStart() { - final String method = "oldPreload()"; - return Task.call( - () -> { - if (mStartTask == null) { - log(method, "Schedule"); - mStartTask = - getOrCreateReactInstanceTask() - .continueWithTask( - task -> { - if (task.isFaulted()) { - destroy( - "oldPreload() failure: " + task.getError().getMessage(), - task.getError()); - mReactHostDelegate.handleInstanceException(task.getError()); - } - - return task; - }, - mBGExecutor) - .makeVoid(); - } - return mStartTask; - }, - mBGExecutor) - .continueWithTask(Task::getResult); - } - - private Task newStart() { - final String method = "newPreload()"; - return Task.call( - () -> { - if (mStartTask == null) { - log(method, "Schedule"); - mStartTask = - waitThenCallNewGetOrCreateReactInstanceTask() - .continueWithTask( - (task) -> { - if (task.isFaulted()) { - mReactHostDelegate.handleInstanceException(task.getError()); - // Wait for destroy to finish - return newGetOrCreateDestroyTask( - "newPreload() failure: " + task.getError().getMessage(), - task.getError()) - .continueWithTask(destroyTask -> Task.forError(task.getError())) - .makeVoid(); - } - return task.makeVoid(); - }, - mBGExecutor); - } - return mStartTask; - }, - mBGExecutor) - .continueWithTask(Task::getResult); - } - /** Initialize and run a React Native surface in a background without mounting real views. */ public Task prerenderSurface(final ReactSurface surface) { final String method = "prerenderSurface(surfaceId = " + surface.getSurfaceID() + ")"; @@ -416,12 +342,6 @@ public class ReactHost implements ReactHostInterface { } } - @ThreadConfined(UI) - private void moveToHostDestroy(@Nullable ReactContext currentContext) { - mReactLifecycleStateManager.moveToOnHostDestroy(currentContext); - mActivity.set(null); - } - /** * Returns current ReactContext which could be nullable if ReactInstance hasn't been created. * @@ -446,6 +366,130 @@ public class ReactHost implements ReactHostInterface { return surface; } + public MemoryPressureRouter getMemoryPressureRouter() { + return mMemoryPressureRouter; + } + + /* package */ boolean isInstanceInitialized() { + final ReactInstance reactInstance = mReactInstanceTaskRef.get().getResult(); + return reactInstance != null; + } + + @ThreadConfined(UI) + @Override + public boolean onBackPressed() { + UiThreadUtil.assertOnUiThread(); + final ReactInstance reactInstance = mReactInstanceTaskRef.get().getResult(); + if (reactInstance == null) { + return false; + } + + DeviceEventManagerModule deviceEventManagerModule = + reactInstance.getNativeModule(DeviceEventManagerModule.class); + if (deviceEventManagerModule == null) { + return false; + } + + deviceEventManagerModule.emitHardwareBackPressed(); + return true; + } + + public @Nullable ReactQueueConfiguration getReactQueueConfiguration() { + synchronized (mReactInstanceTaskRef) { + Task task = mReactInstanceTaskRef.get(); + if (!task.isFaulted() && !task.isCancelled() && task.getResult() != null) { + return task.getResult().getReactQueueConfiguration(); + } + } + return null; + } + + /** Add a listener to be notified of ReactInstance events. */ + public void addReactInstanceEventListener(ReactInstanceEventListener listener) { + mReactInstanceEventListeners.add(listener); + } + + /** Remove a listener previously added with {@link #addReactInstanceEventListener}. */ + public void removeReactInstanceEventListener(ReactInstanceEventListener listener) { + mReactInstanceEventListeners.remove(listener); + } + + /** + * Entrypoint to reload the ReactInstance. If the ReactInstance is destroying, will wait until + * destroy is finished, before reloading. + * + * @param reason {@link String} describing why ReactHost is being reloaded (e.g. js error, user + * tap on reload button) + * @return A task that completes when React Native reloads + */ + public Task reload(String reason) { + final String method = "reload()"; + if (ReactFeatureFlags.enableBridgelessArchitectureNewCreateReloadDestroy) { + return Task.call( + () -> { + if (mDestroyTask != null) { + log( + method, + "Destroying React Native. Waiting for destroy to finish, before reloading React Native."); + return mDestroyTask + .continueWithTask(task -> newGetOrCreateReloadTask(reason), mBGExecutor) + .makeVoid(); + } + + return newGetOrCreateReloadTask(reason).makeVoid(); + }, + mBGExecutor) + .continueWithTask(Task::getResult); + } + + return oldReload(reason); + } + + /** + * Entrypoint to destroy the ReactInstance. If the ReactInstance is reloading, will wait until + * reload is finished, before destroying. + * + * @param reason {@link String} describing why ReactHost is being destroyed (e.g. memmory + * pressure) + * @param ex {@link Exception} exception that caused the trigger to destroy ReactHost (or null) + * This exception will be used to log properly the cause of destroy operation. + * @return A task that completes when React Native gets destroyed. + */ + public Task 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")); + } + + private MemoryPressureListener createMemoryPressureListener(ReactInstance reactInstance) { + WeakReference weakReactInstance = new WeakReference<>(reactInstance); + return (level) -> { + mBGExecutor.execute( + () -> { + @Nullable ReactInstance strongReactInstance = weakReactInstance.get(); + if (strongReactInstance != null) { + strongReactInstance.handleMemoryPressure(level); + } + }); + }; + } + @Nullable /* package */ Activity getCurrentActivity() { return mActivity.get(); @@ -518,54 +562,6 @@ public class ReactHost implements ReactHostInterface { }; } - public MemoryPressureRouter getMemoryPressureRouter() { - return mMemoryPressureRouter; - } - - /* package */ boolean isInstanceInitialized() { - final ReactInstance reactInstance = mReactInstanceTaskRef.get().getResult(); - return reactInstance != null; - } - - @ThreadConfined(UI) - @Override - public boolean onBackPressed() { - UiThreadUtil.assertOnUiThread(); - final ReactInstance reactInstance = mReactInstanceTaskRef.get().getResult(); - if (reactInstance == null) { - return false; - } - - DeviceEventManagerModule deviceEventManagerModule = - reactInstance.getNativeModule(DeviceEventManagerModule.class); - if (deviceEventManagerModule == null) { - return false; - } - - deviceEventManagerModule.emitHardwareBackPressed(); - return true; - } - - public @Nullable ReactQueueConfiguration getReactQueueConfiguration() { - synchronized (mReactInstanceTaskRef) { - Task task = mReactInstanceTaskRef.get(); - if (!task.isFaulted() && !task.isCancelled() && task.getResult() != null) { - return task.getResult().getReactQueueConfiguration(); - } - } - return null; - } - - /** Add a listener to be notified of ReactInstance events. */ - public void addReactInstanceEventListener(ReactInstanceEventListener listener) { - mReactInstanceEventListeners.add(listener); - } - - /** Remove a listener previously added with {@link #addReactInstanceEventListener}. */ - public void removeReactInstanceEventListener(ReactInstanceEventListener listener) { - mReactInstanceEventListeners.remove(listener); - } - /* package */ Task loadBundle(final JSBundleLoader bundleLoader) { final String method = "loadBundle()"; log(method, "Schedule"); @@ -658,6 +654,72 @@ public class ReactHost implements ReactHostInterface { void then(T t); } + @ThreadConfined("ReactHost") + private @Nullable Task mStartTask = null; + + private Task oldStart() { + final String method = "oldPreload()"; + return Task.call( + () -> { + if (mStartTask == null) { + log(method, "Schedule"); + mStartTask = + getOrCreateReactInstanceTask() + .continueWithTask( + task -> { + if (task.isFaulted()) { + destroy( + "oldPreload() failure: " + task.getError().getMessage(), + task.getError()); + mReactHostDelegate.handleInstanceException(task.getError()); + } + + return task; + }, + mBGExecutor) + .makeVoid(); + } + return mStartTask; + }, + mBGExecutor) + .continueWithTask(Task::getResult); + } + + private Task newStart() { + final String method = "newPreload()"; + return Task.call( + () -> { + if (mStartTask == null) { + log(method, "Schedule"); + mStartTask = + waitThenCallNewGetOrCreateReactInstanceTask() + .continueWithTask( + (task) -> { + if (task.isFaulted()) { + mReactHostDelegate.handleInstanceException(task.getError()); + // Wait for destroy to finish + return newGetOrCreateDestroyTask( + "newPreload() failure: " + task.getError().getMessage(), + task.getError()) + .continueWithTask(destroyTask -> Task.forError(task.getError())) + .makeVoid(); + } + return task.makeVoid(); + }, + mBGExecutor); + } + return mStartTask; + }, + mBGExecutor) + .continueWithTask(Task::getResult); + } + + @ThreadConfined(UI) + private void moveToHostDestroy(@Nullable ReactContext currentContext) { + mReactLifecycleStateManager.moveToOnHostDestroy(currentContext); + mActivity.set(null); + } + private void raiseSoftException(String method, String message) { raiseSoftException(method, message, null); } @@ -1045,37 +1107,6 @@ public class ReactHost implements ReactHostInterface { mBridgelessReactStateTracker.enterState("ReactHost{" + mId + "}." + method); } - /** - * Entrypoint to reload the ReactInstance. If the ReactInstance is destroying, will wait until - * destroy is finished, before reloading. - * - * @param reason {@link String} describing why ReactHost is being reloaded (e.g. js error, user - * tap on reload button) - * @return A task that completes when React Native reloads - */ - public Task reload(String reason) { - final String method = "reload()"; - if (ReactFeatureFlags.enableBridgelessArchitectureNewCreateReloadDestroy) { - return Task.call( - () -> { - if (mDestroyTask != null) { - log( - method, - "Destroying React Native. Waiting for destroy to finish, before reloading React Native."); - return mDestroyTask - .continueWithTask(task -> newGetOrCreateReloadTask(reason), mBGExecutor) - .makeVoid(); - } - - return newGetOrCreateReloadTask(reason).makeVoid(); - }, - mBGExecutor) - .continueWithTask(Task::getResult); - } - - return oldReload(reason); - } - @ThreadConfined("ReactHost") private @Nullable Task mReloadTask = null; @@ -1239,38 +1270,6 @@ public class ReactHost implements ReactHostInterface { return mReloadTask; } - /** - * Entrypoint to destroy the ReactInstance. If the ReactInstance is reloading, will wait until - * reload is finished, before destroying. - * - * @param reason {@link String} describing why ReactHost is being destroyed (e.g. memmory - * pressure) - * @param ex {@link Exception} exception that caused the trigger to destroy ReactHost (or null) - * This exception will be used to log properly the cause of destroy operation. - * @return A task that completes when React Native gets destroyed. - */ - public Task 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")); - } - @ThreadConfined("ReactHost") private @Nullable Task mDestroyTask = null;