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
This commit is contained in:
Lulu Wu
2023-10-26 08:31:48 -07:00
committed by Facebook GitHub Bot
parent 1a7a677a90
commit 6b3289bc73
@@ -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<String, ViewManager> 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<ReactPackage> packages = mReactPackages;
if (mDelegate != null) {
List<ReactPackage> 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<ViewManager> viewManagersInPackage =
reactPackage.createViewManagers(mBridgelessReactContext);
for (ViewManager viewManager : viewManagersInPackage) {
mViewManagers.put(viewManager.getName(), viewManager);
}
}
return mViewManagers.get(viewManagerName);
}
private @NonNull Collection<String> getViewManagerNames() {
@@ -542,8 +559,28 @@ final class ReactInstance {
private @NonNull NativeMap getUIManagerConstants() {
List<ViewManager> viewManagers = new ArrayList<ViewManager>();
for (String viewManagerName : getViewManagerNames()) {
viewManagers.add(createViewManager(viewManagerName));
boolean canLoadViewManagersLazily = true;
List<ReactPackage> 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<ViewManager> viewManagersInPackage =
reactPackage.createViewManagers(mBridgelessReactContext);
viewManagers.addAll(viewManagersInPackage);
}
}
Map<String, Object> constants =
UIManagerModule.createConstants(viewManagers, new HashMap<>(), new HashMap<>());