Skip to content

Commit

Permalink
Fall back to eager view manage loading (facebook#41165)
Browse files Browse the repository at this point in the history
Summary:

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
  • Loading branch information
luluwu2032 authored and facebook-github-bot committed Oct 26, 2023
1 parent 1a7a677 commit c059689
Showing 1 changed file with 41 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
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;

Expand All @@ -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;
Expand Down Expand Up @@ -497,8 +499,12 @@ public void registerSegment(int segmentId, String path) {
}

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) {
Expand All @@ -507,6 +513,7 @@ public void registerSegment(int segmentId, String path) {
((ViewManagerOnDemandReactPackage) reactPackage)
.createViewManager(mBridgelessReactContext, viewManagerName);
if (viewManager != null) {
mViewManagers.put(viewManagerName, viewManager);
return viewManager;
}
}
Expand All @@ -515,7 +522,17 @@ public void registerSegment(int segmentId, String path) {
}
}

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() {
Expand All @@ -542,8 +559,28 @@ public void registerSegment(int segmentId, String path) {

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<>());
Expand Down

0 comments on commit c059689

Please sign in to comment.