mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-05-03 07:14:59 +08:00
Add ability to lazy load Native Java Modules
Summary: Utilizes the build time annotation processor ReactModuleSpecProcessor that creates ReactModuleInfos for modules annotated with ReactModule and listed in the ReactModuleList annotation of LazyReactPackages. This way we don't have to instantiate the native modules to get the name, canOverrideExistingModule, and supportsWebWorkers values of the native modules. In the NativeModuleRegistry, we either store these ReactModuleInfos inside of a ModuleHolder or if we can't get the ReactModuleInfo for a specific module we instantiate that module to get the values (as we previously did) to store in a LegacyModuleInfo. Reviewed By: astreet Differential Revision: D3796561 fbshipit-source-id: f8fb9b4993f59b51ce595eb2f2c3425129b28ce5
This commit is contained in:
committed by
Facebook Github Bot 3
parent
1f9b765f81
commit
797ca6c219
@@ -0,0 +1,17 @@
|
||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
package com.facebook.react.module.model;
|
||||
|
||||
/**
|
||||
* Interface for static information about native modules.
|
||||
*/
|
||||
public interface Info {
|
||||
|
||||
String name();
|
||||
|
||||
boolean canOverrideExistingModule();
|
||||
|
||||
boolean supportsWebWorkers();
|
||||
|
||||
boolean needsEagerInit();
|
||||
}
|
||||
@@ -3,14 +3,15 @@
|
||||
package com.facebook.react.module.model;
|
||||
|
||||
/**
|
||||
* Data holder class holding native module specifications.
|
||||
* Data holder class holding native module specifications. {@link ReactModuleSpecProcessor} creates
|
||||
* these so Java modules don't have to be instantiated at React Native start up.
|
||||
*/
|
||||
public class ReactModuleInfo {
|
||||
public class ReactModuleInfo implements Info {
|
||||
|
||||
public final String mName;
|
||||
public final boolean mCanOverrideExistingModule;
|
||||
public final boolean mSupportsWebWorkers;
|
||||
public final boolean mNeedsEagerInit;
|
||||
private final String mName;
|
||||
private final boolean mCanOverrideExistingModule;
|
||||
private final boolean mSupportsWebWorkers;
|
||||
private final boolean mNeedsEagerInit;
|
||||
|
||||
public ReactModuleInfo(
|
||||
String name,
|
||||
@@ -22,4 +23,24 @@ public class ReactModuleInfo {
|
||||
mSupportsWebWorkers = supportsWebWorkers;
|
||||
mNeedsEagerInit = needsEagerInit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return mName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canOverrideExistingModule() {
|
||||
return mCanOverrideExistingModule;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsWebWorkers() {
|
||||
return mSupportsWebWorkers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needsEagerInit() {
|
||||
return mNeedsEagerInit;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
package com.facebook.react.module.model;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Interface for auto-generated class by ReactModuleSpecProcessor.
|
||||
*/
|
||||
public interface ReactModuleInfoProvider {
|
||||
|
||||
Map<Class, ReactModuleInfo> getReactModuleInfos();
|
||||
}
|
||||
@@ -28,6 +28,7 @@ import com.facebook.infer.annotation.SuppressFieldNotInitialized;
|
||||
import com.facebook.react.module.annotations.ReactModule;
|
||||
import com.facebook.react.module.annotations.ReactModuleList;
|
||||
import com.facebook.react.module.model.ReactModuleInfo;
|
||||
import com.facebook.react.module.model.ReactModuleInfoProvider;
|
||||
|
||||
import com.squareup.javapoet.ClassName;
|
||||
import com.squareup.javapoet.CodeBlock;
|
||||
@@ -97,9 +98,8 @@ public class ReactModuleSpecProcessor extends AbstractProcessor {
|
||||
MethodSpec getReactModuleInfosMethod;
|
||||
try {
|
||||
getReactModuleInfosMethod = MethodSpec.methodBuilder("getReactModuleInfos")
|
||||
.addAnnotation(Override.class)
|
||||
.addModifiers(PUBLIC)
|
||||
// TODO add function to native module interface
|
||||
// .addAnnotation(Override.class)
|
||||
.addCode(getCodeBlockForReactModuleInfos(nativeModules))
|
||||
.returns(MAP_TYPE)
|
||||
.build();
|
||||
@@ -108,11 +108,12 @@ public class ReactModuleSpecProcessor extends AbstractProcessor {
|
||||
return false;
|
||||
}
|
||||
|
||||
TypeSpec reactModulesInfosTypeSpec = TypeSpec.classBuilder(
|
||||
fileName + "$$ReactModuleInfoProvider")
|
||||
.addModifiers(Modifier.PUBLIC)
|
||||
.addMethod(getReactModuleInfosMethod)
|
||||
.build();
|
||||
TypeSpec reactModulesInfosTypeSpec = TypeSpec.classBuilder(
|
||||
fileName + "$$ReactModuleInfoProvider")
|
||||
.addModifiers(Modifier.PUBLIC)
|
||||
.addMethod(getReactModuleInfosMethod)
|
||||
.addSuperinterface(ReactModuleInfoProvider.class)
|
||||
.build();
|
||||
|
||||
JavaFile javaFile = JavaFile.builder(packageName, reactModulesInfosTypeSpec)
|
||||
.addFileComment("Generated by " + getClass().getName())
|
||||
@@ -130,30 +131,35 @@ public class ReactModuleSpecProcessor extends AbstractProcessor {
|
||||
|
||||
private CodeBlock getCodeBlockForReactModuleInfos(List<String> nativeModules)
|
||||
throws ReactModuleSpecException {
|
||||
CodeBlock.Builder builder = CodeBlock.builder()
|
||||
.addStatement("$T map = new $T()", MAP_TYPE, INSTANTIATED_MAP_TYPE);
|
||||
CodeBlock.Builder builder = CodeBlock.builder();
|
||||
if (nativeModules == null || nativeModules.isEmpty()) {
|
||||
builder.addStatement("return Collections.emptyMap()");
|
||||
} else {
|
||||
builder.addStatement("$T map = new $T()", MAP_TYPE, INSTANTIATED_MAP_TYPE);
|
||||
|
||||
for (String nativeModule : nativeModules) {
|
||||
String keyString = nativeModule + ".class";
|
||||
for (String nativeModule : nativeModules) {
|
||||
String keyString = nativeModule + ".class";
|
||||
|
||||
TypeElement typeElement = mElements.getTypeElement(nativeModule);
|
||||
ReactModule reactModule = typeElement.getAnnotation(ReactModule.class);
|
||||
if (reactModule == null) {
|
||||
throw new ReactModuleSpecException(keyString + " not found by ReactModuleSpecProcessor. " +
|
||||
"Did you forget to add the @ReactModule annotation the the native module?");
|
||||
TypeElement typeElement = mElements.getTypeElement(nativeModule);
|
||||
ReactModule reactModule = typeElement.getAnnotation(ReactModule.class);
|
||||
if (reactModule == null) {
|
||||
throw new ReactModuleSpecException(
|
||||
keyString + " not found by ReactModuleSpecProcessor. " +
|
||||
"Did you forget to add the @ReactModule annotation the the native module?");
|
||||
}
|
||||
String valueString = new StringBuilder()
|
||||
.append("new ReactModuleInfo(")
|
||||
.append("\"").append(reactModule.name()).append("\"").append(", ")
|
||||
.append(reactModule.canOverrideExistingModule()).append(", ")
|
||||
.append(reactModule.supportsWebWorkers()).append(", ")
|
||||
.append(reactModule.needsEagerInit())
|
||||
.append(")")
|
||||
.toString();
|
||||
|
||||
builder.addStatement("map.put(" + keyString + ", " + valueString + ")");
|
||||
}
|
||||
String valueString = new StringBuilder()
|
||||
.append("new ReactModuleInfo(")
|
||||
.append("\"").append(reactModule.name()).append("\"").append(", ")
|
||||
.append(reactModule.canOverrideExistingModule()).append(", ")
|
||||
.append(reactModule.supportsWebWorkers()).append(", ")
|
||||
.append(reactModule.needsEagerInit())
|
||||
.append(")")
|
||||
.toString();
|
||||
|
||||
builder.addStatement("map.put(" + keyString + ", " + valueString + ")");
|
||||
builder.addStatement("return map");
|
||||
}
|
||||
builder.addStatement("return map");
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user