mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-05-03 23:35:06 +08:00
Prevent class loading for lazy native modules
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
This commit is contained in:
committed by
Facebook Github Bot
parent
d891ee1dee
commit
c8e000b19a
@@ -15,16 +15,22 @@ public class ReactModuleInfo {
|
||||
private final boolean mCanOverrideExistingModule;
|
||||
private final boolean mNeedsEagerInit;
|
||||
private final boolean mHasConstants;
|
||||
private final boolean mIsCxxModule;
|
||||
private final boolean mHasOnBatchCompleteListener;
|
||||
|
||||
public ReactModuleInfo(
|
||||
String name,
|
||||
boolean canOverrideExistingModule,
|
||||
boolean needsEagerInit,
|
||||
boolean hasConstants) {
|
||||
boolean hasConstants,
|
||||
boolean isCxxModule,
|
||||
boolean hasOnBatchCompleteListener) {
|
||||
mName = name;
|
||||
mCanOverrideExistingModule = canOverrideExistingModule;
|
||||
mNeedsEagerInit = needsEagerInit;
|
||||
mHasConstants = hasConstants;
|
||||
mIsCxxModule = isCxxModule;
|
||||
mHasOnBatchCompleteListener = hasOnBatchCompleteListener;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
@@ -42,4 +48,10 @@ public class ReactModuleInfo {
|
||||
public boolean hasConstants() {
|
||||
return mHasConstants;
|
||||
}
|
||||
|
||||
public boolean isCxxModule() {return mIsCxxModule; }
|
||||
|
||||
public boolean hasOnBatchCompleteListener() {
|
||||
return mHasOnBatchCompleteListener;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
package com.facebook.react.module.processing;
|
||||
|
||||
import com.facebook.react.bridge.CxxModuleWrapper;
|
||||
import com.facebook.react.bridge.OnBatchCompleteListener;
|
||||
import javax.annotation.processing.AbstractProcessor;
|
||||
import javax.annotation.processing.Filer;
|
||||
import javax.annotation.processing.Messager;
|
||||
@@ -21,6 +23,7 @@ import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.type.MirroredTypesException;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
import javax.lang.model.util.Elements;
|
||||
import javax.lang.model.util.Types;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
@@ -72,6 +75,7 @@ public class ReactModuleSpecProcessor extends AbstractProcessor {
|
||||
private Elements mElements;
|
||||
@SuppressFieldNotInitialized
|
||||
private Messager mMessager;
|
||||
private Types mTypes;
|
||||
|
||||
@Override
|
||||
public synchronized void init(ProcessingEnvironment processingEnv) {
|
||||
@@ -80,6 +84,7 @@ public class ReactModuleSpecProcessor extends AbstractProcessor {
|
||||
mFiler = processingEnv.getFiler();
|
||||
mElements = processingEnv.getElementUtils();
|
||||
mMessager = processingEnv.getMessager();
|
||||
mTypes = processingEnv.getTypeUtils();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -154,6 +159,9 @@ public class ReactModuleSpecProcessor extends AbstractProcessor {
|
||||
} else {
|
||||
builder.addStatement("$T map = new $T()", MAP_TYPE, INSTANTIATED_MAP_TYPE);
|
||||
|
||||
TypeMirror cxxModuleWrapperTypeMirror = mElements.getTypeElement(CxxModuleWrapper.class.getName()).asType();
|
||||
TypeMirror onBatchCompleteListenerTypeMirror = mElements.getTypeElement(OnBatchCompleteListener.class.getName()).asType();
|
||||
|
||||
for (String nativeModule : nativeModules) {
|
||||
String keyString = nativeModule;
|
||||
|
||||
@@ -163,6 +171,7 @@ public class ReactModuleSpecProcessor extends AbstractProcessor {
|
||||
keyString + " not found by ReactModuleSpecProcessor. " +
|
||||
"Did you misspell the module?");
|
||||
}
|
||||
|
||||
ReactModule reactModule = typeElement.getAnnotation(ReactModule.class);
|
||||
if (reactModule == null) {
|
||||
throw new ReactModuleSpecException(
|
||||
@@ -182,12 +191,27 @@ public class ReactModuleSpecProcessor extends AbstractProcessor {
|
||||
name -> name.contentEquals("getConstants") || name.contentEquals("getTypedExportedConstants"));
|
||||
}
|
||||
|
||||
boolean isCxxModule = mTypes.isAssignable(typeElement.asType(), cxxModuleWrapperTypeMirror);
|
||||
boolean hasOnBatchCompleteListener = false;
|
||||
try {
|
||||
hasOnBatchCompleteListener = mTypes.isAssignable(typeElement.asType(), onBatchCompleteListenerTypeMirror);
|
||||
} catch (RuntimeException e) {
|
||||
// This is SUPER ugly, but we need to do this, especially for AsyncStorageModule which implements ModuleDataCleaner
|
||||
// In the case of that specific class, we get the exception
|
||||
// com.sun.tools.javac.code.Symbol$CompletionFailure: class file for ModuleDataCleaner not found.
|
||||
// The exception is caused because the class is not loaded the first time. However, catching it and
|
||||
// running it again the second time loads the class and does what the following statement originally intended
|
||||
hasOnBatchCompleteListener = mTypes.isAssignable(typeElement.asType(), onBatchCompleteListenerTypeMirror);
|
||||
}
|
||||
|
||||
String valueString = new StringBuilder()
|
||||
.append("new ReactModuleInfo(")
|
||||
.append("\"").append(reactModule.name()).append("\"").append(", ")
|
||||
.append(reactModule.canOverrideExistingModule()).append(", ")
|
||||
.append(reactModule.needsEagerInit()).append(", ")
|
||||
.append(hasConstants)
|
||||
.append(hasConstants).append(", ")
|
||||
.append(isCxxModule).append(", ")
|
||||
.append(hasOnBatchCompleteListener)
|
||||
.append(")")
|
||||
.toString();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user