Refactored NativeModuleRegistryBuilder

Summary: The logic in NativeModuleRegistryBuilder.processPackage was getting pretty complex with lot of branches. Moved the logic to get actual packages into each of the packages, instead of having it in NativeModuleRegistryBuilder.

Reviewed By: achen1

Differential Revision: D9618140

fbshipit-source-id: 4be82ec65b0bd92f11f8b77044004e10c9d3b1a1
This commit is contained in:
Ram N
2018-09-07 10:26:20 -07:00
committed by Facebook Github Bot
parent b1d205a28f
commit 875f70b8b6
5 changed files with 194 additions and 119 deletions
@@ -1,14 +1,15 @@
/**
* Copyright (c) 2015-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.
* <p>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 static com.facebook.systrace.Systrace.TRACE_TAG_REACT_JAVA_BRIDGE;
import android.support.annotation.NonNull;
import com.facebook.react.bridge.ModuleHolder;
import com.facebook.react.bridge.ModuleSpec;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
@@ -20,13 +21,14 @@ import com.facebook.react.uimanager.ViewManager;
import com.facebook.systrace.SystraceMessage;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* React package supporting lazy creation of native modules.
*
* TODO(t11394819): Make this default and deprecate ReactPackage
* <p>TODO(t11394819): Make this default and deprecate ReactPackage
*/
public abstract class LazyReactPackage implements ReactPackage {
@@ -34,8 +36,9 @@ public abstract class LazyReactPackage implements ReactPackage {
LazyReactPackage lazyReactPackage) {
Class<?> reactModuleInfoProviderClass;
try {
reactModuleInfoProviderClass = Class.forName(
lazyReactPackage.getClass().getCanonicalName() + "$$ReactModuleInfoProvider");
reactModuleInfoProviderClass =
Class.forName(
lazyReactPackage.getClass().getCanonicalName() + "$$ReactModuleInfoProvider");
} catch (ClassNotFoundException e) {
// In OSS case, when the annotation processor does not run, we fall back to non-lazy mode
// For this, we simply return an empty moduleMap.
@@ -50,41 +53,105 @@ public abstract class LazyReactPackage implements ReactPackage {
}
if (reactModuleInfoProviderClass == null) {
throw new RuntimeException("ReactModuleInfoProvider class for " +
lazyReactPackage.getClass().getCanonicalName() + " not found.");
throw new RuntimeException(
"ReactModuleInfoProvider class for "
+ lazyReactPackage.getClass().getCanonicalName()
+ " not found.");
}
try {
return (ReactModuleInfoProvider) reactModuleInfoProviderClass.newInstance();
} catch (InstantiationException e) {
throw new RuntimeException(
"Unable to instantiate ReactModuleInfoProvider for " + lazyReactPackage.getClass(),
e);
"Unable to instantiate ReactModuleInfoProvider for " + lazyReactPackage.getClass(), e);
} catch (IllegalAccessException e) {
throw new RuntimeException(
"Unable to instantiate ReactModuleInfoProvider for " + lazyReactPackage.getClass(),
e);
"Unable to instantiate ReactModuleInfoProvider for " + lazyReactPackage.getClass(), e);
}
}
/**
* We return an iterable
*
* @param reactContext
* @return
*/
/* package */
Iterable<ModuleHolder> getNativeModuleIterator(final ReactApplicationContext reactContext) {
final List<String> eagerNativeModules = getEagerNativeModules();
final Map<String, ReactModuleInfo> reactModuleInfoMap =
getReactModuleInfoProvider().getReactModuleInfos();
final List<ModuleSpec> nativeModules = getNativeModules(reactContext);
return new Iterable<ModuleHolder>() {
@NonNull
@Override
public Iterator<ModuleHolder> iterator() {
return new Iterator<ModuleHolder>() {
int position = 0;
@Override
public ModuleHolder next() {
ModuleSpec moduleSpec = nativeModules.get(position++);
String name = moduleSpec.getName();
ReactModuleInfo reactModuleInfo = reactModuleInfoMap.get(name);
ModuleHolder moduleHolder;
if (reactModuleInfo == null || eagerNativeModules.contains(name)) {
NativeModule module;
ReactMarker.logMarker(ReactMarkerConstants.CREATE_MODULE_START, name);
try {
module = moduleSpec.getProvider().get();
} finally {
ReactMarker.logMarker(ReactMarkerConstants.CREATE_MODULE_END);
}
moduleHolder = new ModuleHolder(module);
} else {
moduleHolder = new ModuleHolder(reactModuleInfo, moduleSpec.getProvider());
}
return moduleHolder;
}
@Override
public boolean hasNext() {
return position < nativeModules.size();
}
@Override
public void remove() {
throw new UnsupportedOperationException("Cannot remove native modules from the list");
}
};
}
};
}
/**
* @param reactContext react application context that can be used to create modules
* @return list of module specs that can create the native modules
*/
public abstract List<ModuleSpec> getNativeModules(
ReactApplicationContext reactContext);
protected abstract List<ModuleSpec> getNativeModules(ReactApplicationContext reactContext);
/** @return list of native modules which should be eagerly initialized. */
protected List<String> getEagerNativeModules() {
return Collections.emptyList();
}
/**
* This is only used when a LazyReactPackage is a part of {@link CompositeReactPackage} Once we
* deprecate {@link CompositeReactPackage}, this can be removed too
*
* @param reactContext react application context that can be used to create modules
* @return
*/
@Override
public final List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
for (ModuleSpec holder : getNativeModules(reactContext)) {
NativeModule nativeModule;
SystraceMessage.beginSection(TRACE_TAG_REACT_JAVA_BRIDGE, "createNativeModule")
.arg("module", holder.getType())
.flush();
ReactMarker.logMarker(
ReactMarkerConstants.CREATE_MODULE_START,
holder.getName());
.arg("module", holder.getType())
.flush();
ReactMarker.logMarker(ReactMarkerConstants.CREATE_MODULE_START, holder.getName());
try {
nativeModule = holder.getProvider().get();
} finally {
@@ -95,15 +162,6 @@ public abstract class LazyReactPackage implements ReactPackage {
}
return modules;
}
/**
* @return list of native modules which should be eagerly initialized.
*/
public List<String> getEagerNativeModules() {
return Collections.emptyList();
}
/**
* @param reactContext react application context that can be used to create View Managers.
* @return list of module specs that can create the View Managers.