From 6b3289bc731eb5c4855dbd349d926fa2e4e3595b Mon Sep 17 00:00:00 2001 From: Lulu Wu Date: Thu, 26 Oct 2023 08:31:48 -0700 Subject: [PATCH] Fall back to eager view manage loading (#41165) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/41165 Currently Bridgeless forces lazy view manager loading, each ReactPackage must implement ```ViewManagerOnDemandReactPackage```. This can bring extra hassle for OSS users in migration. This diff add backward compatibility by falling back to eager view manage loading, after detecting any ReactPackage of current application NOT a subclass of ```ViewManagerOnDemandReactPackage```. Changelog: [Android][Changed] - Fall back to eager view manage loading for Bridgeless Reviewed By: cortinico Differential Revision: D50556405 fbshipit-source-id: 32357d1934068d0fa0f2b7cb46b54f2f41b3e24f --- .../facebook/react/runtime/ReactInstance.java | 45 +++++++++++++++++-- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactInstance.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactInstance.java index 1c5fc2a9db1..4da3827ab8d 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactInstance.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactInstance.java @@ -71,6 +71,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import javax.annotation.Nullable; import kotlin.jvm.functions.Function1; @@ -94,6 +95,7 @@ final class ReactInstance { private final TurboModuleManager mTurboModuleManager; private final FabricUIManager mFabricUIManager; private final JavaTimerManager mJavaTimerManager; + private final Map mViewManagers = new ConcurrentHashMap<>(); @DoNotStrip @Nullable private ComponentNameResolverManager mComponentNameResolverManager; @DoNotStrip @Nullable private UIConstantsProviderManager mUIConstantsProviderManager; @@ -497,8 +499,12 @@ final class ReactInstance { } private @Nullable ViewManager createViewManager(String viewManagerName) { + // Return cached view manager if available, no matter it's eagerly or lazily loaded + if (mViewManagers.containsKey(viewManagerName)) { + return mViewManagers.get(viewManagerName); + } + List packages = mReactPackages; if (mDelegate != null) { - List packages = mReactPackages; if (packages != null) { synchronized (packages) { for (ReactPackage reactPackage : packages) { @@ -507,6 +513,7 @@ final class ReactInstance { ((ViewManagerOnDemandReactPackage) reactPackage) .createViewManager(mBridgelessReactContext, viewManagerName); if (viewManager != null) { + mViewManagers.put(viewManagerName, viewManager); return viewManager; } } @@ -515,7 +522,17 @@ final class ReactInstance { } } - return null; + // Once a view manager is not found in all react packages via lazy loading, fall back to default + // implementation: eagerly initialize all view managers + for (ReactPackage reactPackage : packages) { + List viewManagersInPackage = + reactPackage.createViewManagers(mBridgelessReactContext); + for (ViewManager viewManager : viewManagersInPackage) { + mViewManagers.put(viewManager.getName(), viewManager); + } + } + + return mViewManagers.get(viewManagerName); } private @NonNull Collection getViewManagerNames() { @@ -542,8 +559,28 @@ final class ReactInstance { private @NonNull NativeMap getUIManagerConstants() { List viewManagers = new ArrayList(); - for (String viewManagerName : getViewManagerNames()) { - viewManagers.add(createViewManager(viewManagerName)); + boolean canLoadViewManagersLazily = true; + + List packages = mReactPackages; + for (ReactPackage reactPackage : packages) { + if (!(reactPackage instanceof ViewManagerOnDemandReactPackage)) { + canLoadViewManagersLazily = false; + break; + } + } + // 1, Retrive view managers via on demand loading + if (canLoadViewManagersLazily) { + for (String viewManagerName : getViewManagerNames()) { + viewManagers.add(createViewManager(viewManagerName)); + } + } else { + // 2, There are packages that don't implement ViewManagerOnDemandReactPackage so we retrieve + // view managers via eager loading + for (ReactPackage reactPackage : packages) { + List viewManagersInPackage = + reactPackage.createViewManagers(mBridgelessReactContext); + viewManagers.addAll(viewManagersInPackage); + } } Map constants = UIManagerModule.createConstants(viewManagers, new HashMap<>(), new HashMap<>());