mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
c8e000b19a
Summary: When native modules use `LazyReactPackage`, the modules themselves are not initialized. However, they still use the class names, causing the classes to load. This diff removes the need to perform any class loads. Any properties of the classes that are required are now populated in the `ReactModuleInfo` of that class. Note that this diff itself does not prevent class loading since any references to `*.class` in `LazyReactpackage` needs to be removed in a consequent diff Reviewed By: achen1 Differential Revision: D8950025 fbshipit-source-id: 80ddf7e1f33bf2af0db1bd262069795de77ec611
140 lines
5.3 KiB
Java
140 lines
5.3 KiB
Java
// Copyright (c) 2004-present, Facebook, Inc.
|
|
|
|
// This source code is licensed under the MIT license found in the
|
|
// LICENSE file in the root directory of this source tree.
|
|
|
|
package com.facebook.react;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
|
|
import com.facebook.common.logging.FLog;
|
|
import com.facebook.react.bridge.BaseJavaModule;
|
|
import com.facebook.react.bridge.ModuleSpec;
|
|
import com.facebook.react.bridge.ModuleHolder;
|
|
import com.facebook.react.bridge.NativeModule;
|
|
import com.facebook.react.bridge.NativeModuleRegistry;
|
|
import com.facebook.react.bridge.OnBatchCompleteListener;
|
|
import com.facebook.react.bridge.ReactApplicationContext;
|
|
import com.facebook.react.bridge.ReactMarker;
|
|
import com.facebook.react.bridge.ReactMarkerConstants;
|
|
import com.facebook.react.common.ReactConstants;
|
|
import com.facebook.react.module.model.ReactModuleInfo;
|
|
|
|
/**
|
|
* Helper class to build NativeModuleRegistry.
|
|
*/
|
|
public class NativeModuleRegistryBuilder {
|
|
|
|
private final ReactApplicationContext mReactApplicationContext;
|
|
private final ReactInstanceManager mReactInstanceManager;
|
|
private final boolean mLazyNativeModulesEnabled;
|
|
|
|
private final Map<String, ModuleHolder> mModules = new HashMap<>();
|
|
private final Map<String,String> namesToType = new HashMap<>();
|
|
|
|
public NativeModuleRegistryBuilder(
|
|
ReactApplicationContext reactApplicationContext,
|
|
ReactInstanceManager reactInstanceManager,
|
|
boolean lazyNativeModulesEnabled) {
|
|
mReactApplicationContext = reactApplicationContext;
|
|
mReactInstanceManager = reactInstanceManager;
|
|
// TODO T32034141 Remove mLazyNativeModulesEnabled
|
|
mLazyNativeModulesEnabled = lazyNativeModulesEnabled;
|
|
}
|
|
|
|
public void processPackage(ReactPackage reactPackage) {
|
|
if (reactPackage instanceof LazyReactPackage) {
|
|
LazyReactPackage lazyReactPackage = (LazyReactPackage) reactPackage;
|
|
List<ModuleSpec> moduleSpecs = lazyReactPackage.getNativeModules(mReactApplicationContext);
|
|
Map<String, ReactModuleInfo> reactModuleInfoMap =
|
|
lazyReactPackage.getReactModuleInfoProvider().getReactModuleInfos();
|
|
|
|
for (ModuleSpec moduleSpec : moduleSpecs) {
|
|
String className = moduleSpec.getClassName();
|
|
ReactModuleInfo reactModuleInfo = reactModuleInfoMap.get(className);
|
|
ModuleHolder moduleHolder;
|
|
if (reactModuleInfo == null) {
|
|
NativeModule module;
|
|
ReactMarker.logMarker(
|
|
ReactMarkerConstants.CREATE_MODULE_START,
|
|
moduleSpec.getType().getName());
|
|
try {
|
|
module = moduleSpec.getProvider().get();
|
|
} finally {
|
|
ReactMarker.logMarker(ReactMarkerConstants.CREATE_MODULE_END);
|
|
}
|
|
moduleHolder = new ModuleHolder(module);
|
|
} else {
|
|
moduleHolder = new ModuleHolder(reactModuleInfo, moduleSpec.getProvider());
|
|
}
|
|
|
|
String name = moduleHolder.getName();
|
|
putModuleTypeAndHolderToModuleMaps(className, name, moduleHolder);
|
|
}
|
|
} else {
|
|
FLog.d(
|
|
ReactConstants.TAG,
|
|
reactPackage.getClass().getSimpleName()
|
|
+ " is not a LazyReactPackage, falling back to old version.");
|
|
List<NativeModule> nativeModules;
|
|
if (reactPackage instanceof ReactInstancePackage) {
|
|
ReactInstancePackage reactInstancePackage = (ReactInstancePackage) reactPackage;
|
|
nativeModules =
|
|
reactInstancePackage.createNativeModules(
|
|
mReactApplicationContext, mReactInstanceManager);
|
|
} else {
|
|
nativeModules = reactPackage.createNativeModules(mReactApplicationContext);
|
|
}
|
|
for (NativeModule nativeModule : nativeModules) {
|
|
addNativeModule(nativeModule);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void addNativeModule(NativeModule nativeModule) {
|
|
String name = nativeModule.getName();
|
|
Class<? extends NativeModule> type = nativeModule.getClass();
|
|
putModuleTypeAndHolderToModuleMaps(type.getName(), name, new ModuleHolder(nativeModule));
|
|
}
|
|
|
|
private void putModuleTypeAndHolderToModuleMaps(
|
|
String className, String underName, ModuleHolder moduleHolder)
|
|
throws IllegalStateException {
|
|
if (namesToType.containsKey(underName)) {
|
|
String existingNativeModule = namesToType.get(underName);
|
|
if (!moduleHolder.getCanOverrideExistingModule()) {
|
|
throw new IllegalStateException(
|
|
"Native module "
|
|
+ className
|
|
+ " tried to override "
|
|
+ existingNativeModule
|
|
+ " for module name "
|
|
+ underName
|
|
+ ". Check the getPackages() method in MainApplication.java, it might be "
|
|
+ "that module is being created twice. "
|
|
+ "If this was your intention, set canOverrideExistingModule=true");
|
|
}
|
|
|
|
mModules.remove(existingNativeModule);
|
|
}
|
|
|
|
namesToType.put(underName, className);
|
|
mModules.put(className, moduleHolder);
|
|
}
|
|
|
|
public NativeModuleRegistry build() {
|
|
ArrayList<ModuleHolder> batchCompleteListenerModules = new ArrayList<>();
|
|
for (Map.Entry<String, ModuleHolder> entry : mModules.entrySet()) {
|
|
if (entry.getValue().hasOnBatchCompleteListener()) {
|
|
batchCompleteListenerModules.add(entry.getValue());
|
|
}
|
|
}
|
|
|
|
return new NativeModuleRegistry(
|
|
mReactApplicationContext, mModules, batchCompleteListenerModules);
|
|
}
|
|
}
|