don't allow fallback implementation when Lazy Native modules is enabled

Reviewed By: achen1

Differential Revision: D4019360

fbshipit-source-id: af5fffd1e80cdf99ff9af743eafff1412cac8e58
This commit is contained in:
Aaron Chiu 2016-10-20 05:31:49 -07:00 committed by Facebook Github Bot
parent fb4f34bc9b
commit e16251b46d
5 changed files with 59 additions and 55 deletions

View File

@ -25,6 +25,7 @@ import com.facebook.react.devsupport.HMRClient;
import com.facebook.react.devsupport.JSCHeapCapture;
import com.facebook.react.devsupport.JSCSamplingProfiler;
import com.facebook.react.module.annotations.ReactModuleList;
import com.facebook.react.module.model.ReactModuleInfoProvider;
import com.facebook.react.modules.core.HeadlessJsTaskSupportModule;
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
import com.facebook.react.modules.core.DeviceEventManagerModule;
@ -187,6 +188,12 @@ import static com.facebook.react.bridge.ReactMarkerConstants.CREATE_UI_MANAGER_M
return jsModules;
}
@Override
public ReactModuleInfoProvider getReactModuleInfoProvider() {
// This has to be done via reflection or we break open source.
return LazyReactPackage.getReactModuleInfoProviderViaReflection(this);
}
private UIManagerModule createUIManager(ReactApplicationContext reactContext) {
ReactMarker.logMarker(CREATE_UI_MANAGER_MODULE_START);
Systrace.beginSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "createUIManagerModule");

View File

@ -16,6 +16,7 @@ import java.util.List;
import com.facebook.react.bridge.ModuleSpec;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.module.model.ReactModuleInfoProvider;
import com.facebook.react.uimanager.ViewManager;
import com.facebook.systrace.Systrace;
import com.facebook.systrace.SystraceMessage;
@ -28,6 +29,35 @@ import static com.facebook.systrace.Systrace.TRACE_TAG_REACT_JAVA_BRIDGE;
* TODO(t11394819): Make this default and deprecate ReactPackage
*/
public abstract class LazyReactPackage implements ReactPackage {
public static ReactModuleInfoProvider getReactModuleInfoProviderViaReflection(
LazyReactPackage lazyReactPackage) {
Class<?> reactModuleInfoProviderClass;
try {
reactModuleInfoProviderClass = Class.forName(
lazyReactPackage.getClass().getCanonicalName() + "$$ReactModuleInfoProvider");
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
if (reactModuleInfoProviderClass == null) {
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);
} catch (IllegalAccessException e) {
throw new RuntimeException(
"Unable to instantiate ReactModuleInfoProvider for " + lazyReactPackage.getClass(),
e);
}
}
/**
* @param reactContext react application context that can be used to create modules
* @return list of module specs that can create the native modules
@ -72,4 +102,6 @@ public abstract class LazyReactPackage implements ReactPackage {
}
return viewManagers;
}
public abstract ReactModuleInfoProvider getReactModuleInfoProvider();
}

View File

@ -940,15 +940,21 @@ import static com.facebook.systrace.Systrace.TRACE_TAG_REACT_JAVA_BRIDGE;
.flush();
if (mLazyNativeModulesEnabled && reactPackage instanceof LazyReactPackage) {
LazyReactPackage lazyReactPackage = (LazyReactPackage) reactPackage;
if (addReactModuleInfos(lazyReactPackage, reactContext, moduleSpecs, reactModuleInfoMap)) {
moduleSpecs.addAll(lazyReactPackage.getNativeModules(reactContext));
ReactModuleInfoProvider instance = lazyReactPackage.getReactModuleInfoProvider();
Map<Class, ReactModuleInfo> map = instance.getReactModuleInfos();
if (!map.isEmpty()) {
reactModuleInfoMap.putAll(map);
}
moduleSpecs.addAll(lazyReactPackage.getNativeModules(reactContext));
} else {
FLog.d(
ReactConstants.TAG,
reactPackage.getClass().getSimpleName() +
" is not a LazyReactPackage, falling back to old version");
addEagerModuleProviders(reactPackage, reactContext, moduleSpecs);
" is not a LazyReactPackage, falling back to old version.");
for (NativeModule nativeModule : reactPackage.createNativeModules(reactContext)) {
moduleSpecs.add(
new ModuleSpec(nativeModule.getClass(), new EagerModuleProvider(nativeModule)));
}
}
for (Class<? extends JavaScriptModule> jsModuleClass : reactPackage.createJSModules()) {
@ -957,55 +963,6 @@ import static com.facebook.systrace.Systrace.TRACE_TAG_REACT_JAVA_BRIDGE;
Systrace.endSection(TRACE_TAG_REACT_JAVA_BRIDGE);
}
private boolean addReactModuleInfos(
LazyReactPackage lazyReactPackage,
ReactApplicationContext reactApplicationContext,
List<ModuleSpec> moduleSpecs,
Map<Class, ReactModuleInfo> reactModuleInfoMap) {
Class<?> reactModuleInfoProviderClass = null;
try {
reactModuleInfoProviderClass = Class.forName(
lazyReactPackage.getClass().getCanonicalName() + "$$ReactModuleInfoProvider");
} catch (ClassNotFoundException e) {
FLog.w(
TAG,
"Could not find generated ReactModuleInfoProvider for " + lazyReactPackage.getClass());
// Fallback to non-lazy method.
addEagerModuleProviders(lazyReactPackage, reactApplicationContext, moduleSpecs);
return false;
}
if (reactModuleInfoProviderClass != null) {
ReactModuleInfoProvider instance;
try {
instance = (ReactModuleInfoProvider) reactModuleInfoProviderClass.newInstance();
} catch (InstantiationException e) {
throw new RuntimeException(
"Unable to instantiate ReactModuleInfoProvider for " + lazyReactPackage.getClass(),
e);
} catch (IllegalAccessException e) {
throw new RuntimeException(
"Unable to instantiate ReactModuleInfoProvider for " + lazyReactPackage.getClass(),
e);
}
Map<Class, ReactModuleInfo> map = instance.getReactModuleInfos();
if (!map.isEmpty()) {
reactModuleInfoMap.putAll(map);
}
}
return true;
}
private void addEagerModuleProviders(
ReactPackage reactPackage,
ReactApplicationContext reactApplicationContext,
List<ModuleSpec> moduleSpecs) {
for (NativeModule nativeModule : reactPackage.createNativeModules(reactApplicationContext)) {
moduleSpecs.add(
new ModuleSpec(nativeModule.getClass(), new EagerModuleProvider(nativeModule)));
}
}
private void moveReactContextToCurrentLifecycleState() {
if (mLifecycleState == LifecycleState.RESUMED) {
moveToResumedLifecycleState(true);

View File

@ -8,10 +8,12 @@ android_library(
react_native_dep('third-party/android/support/v4:lib-support-v4'),
react_native_dep('third-party/java/infer-annotations:infer-annotations'),
react_native_dep('third-party/java/jsr-305:jsr-305'),
react_native_target('java/com/facebook/react:react'),
react_native_target('java/com/facebook/react/animated:animated'),
react_native_target('java/com/facebook/react/bridge:bridge'),
react_native_target('java/com/facebook/react/common:common'),
react_native_target('java/com/facebook/react/devsupport:devsupport'),
react_native_target('java/com/facebook/react/module/model:model'),
react_native_target('java/com/facebook/react/modules/appstate:appstate'),
react_native_target('java/com/facebook/react/modules/camera:camera'),
react_native_target('java/com/facebook/react/modules/clipboard:clipboard'),
@ -46,14 +48,13 @@ android_library(
react_native_target('java/com/facebook/react/views/slider:slider'),
react_native_target('java/com/facebook/react/views/swiperefresh:swiperefresh'),
react_native_target('java/com/facebook/react/views/switchview:switchview'),
react_native_target('java/com/facebook/react/views/text/frescosupport:frescosupport'),
react_native_target('java/com/facebook/react/views/text:text'),
react_native_target('java/com/facebook/react/views/text/frescosupport:frescosupport'),
react_native_target('java/com/facebook/react/views/textinput:textinput'),
react_native_target('java/com/facebook/react/views/toolbar:toolbar'),
react_native_target('java/com/facebook/react/views/view:view'),
react_native_target('java/com/facebook/react/views/viewpager:viewpager'),
react_native_target('java/com/facebook/react/views/webview:webview'),
react_native_target('java/com/facebook/react:react'),
react_native_target('res:shell'),
],
visibility = [

View File

@ -21,6 +21,7 @@ import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.ModuleSpec;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.module.model.ReactModuleInfoProvider;
import com.facebook.react.modules.appstate.AppStateModule;
import com.facebook.react.modules.camera.CameraRollManager;
import com.facebook.react.modules.camera.ImageEditingManager;
@ -250,4 +251,10 @@ public class MainReactPackage extends LazyReactPackage {
new RecyclerViewBackedScrollViewManager(),
new SwipeRefreshLayoutManager());
}
@Override
public ReactModuleInfoProvider getReactModuleInfoProvider() {
// This has to be done via reflection or we break open source.
return LazyReactPackage.getReactModuleInfoProviderViaReflection(this);
}
}