mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
42146a7a4a
Summary: In OSS, during gradle build, the ReactModuleSpecProcess annotation-processor does not run. As a result, the `ReactModuleInfo` that we need for CoreReactPackage is not generated, resulting in a runtime error. The fix is to make LazyReactPackage revert to what it was doing earlier. In `NativeModuleRegistryBuilder`, if we dont find `ReactModuleInfo` for any `ModuleSpec`, we eagerly instantiate the module and get all the `ReactModuleInfo` from it. By returning an emoy collection if the class is not available, we force the modules in `CoreReactPackage` to use this codepath instead. The alternate fix would be to ensure that the annotation processor runs in gradle/OSS. However, the annotation processor will be removed eventually in the future, and we will also be move to generating them for JS, so that work will soon be irrelevant. Reviewed By: fkgozali, achen1 Differential Revision: D9130517 fbshipit-source-id: 469cf0e32a2f3650f098547667b3cd09a63eb1a0
123 lines
4.4 KiB
Java
123 lines
4.4 KiB
Java
/**
|
|
* 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.
|
|
*/
|
|
|
|
package com.facebook.react;
|
|
|
|
import static com.facebook.systrace.Systrace.TRACE_TAG_REACT_JAVA_BRIDGE;
|
|
|
|
import com.facebook.react.bridge.ModuleSpec;
|
|
import com.facebook.react.bridge.NativeModule;
|
|
import com.facebook.react.bridge.ReactApplicationContext;
|
|
import com.facebook.react.bridge.ReactMarker;
|
|
import com.facebook.react.bridge.ReactMarkerConstants;
|
|
import com.facebook.react.module.model.ReactModuleInfo;
|
|
import com.facebook.react.module.model.ReactModuleInfoProvider;
|
|
import com.facebook.react.uimanager.ViewManager;
|
|
import com.facebook.systrace.SystraceMessage;
|
|
import java.util.ArrayList;
|
|
import java.util.Collections;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
|
|
/**
|
|
* React package supporting lazy creation of native modules.
|
|
*
|
|
* 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) {
|
|
// 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.
|
|
// NativeModuleRegistryBuilder will eagerly get all the modules, and get the info from the
|
|
// modules directly
|
|
return new ReactModuleInfoProvider() {
|
|
@Override
|
|
public Map<String, ReactModuleInfo> getReactModuleInfos() {
|
|
return Collections.emptyMap();
|
|
}
|
|
};
|
|
}
|
|
|
|
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
|
|
*/
|
|
public abstract List<ModuleSpec> getNativeModules(
|
|
ReactApplicationContext reactContext);
|
|
|
|
@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.getClassName());
|
|
try {
|
|
nativeModule = holder.getProvider().get();
|
|
} finally {
|
|
ReactMarker.logMarker(ReactMarkerConstants.CREATE_MODULE_END);
|
|
SystraceMessage.endSection(TRACE_TAG_REACT_JAVA_BRIDGE).flush();
|
|
}
|
|
modules.add(nativeModule);
|
|
}
|
|
return modules;
|
|
}
|
|
|
|
/**
|
|
* @param reactContext react application context that can be used to create View Managers.
|
|
* @return list of module specs that can create the View Managers.
|
|
*/
|
|
public List<ModuleSpec> getViewManagers(ReactApplicationContext reactContext) {
|
|
return Collections.emptyList();
|
|
}
|
|
|
|
@Override
|
|
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
|
|
List<ModuleSpec> viewManagerModuleSpecs = getViewManagers(reactContext);
|
|
if (viewManagerModuleSpecs == null || viewManagerModuleSpecs.isEmpty()) {
|
|
return Collections.emptyList();
|
|
}
|
|
|
|
List<ViewManager> viewManagers = new ArrayList<>();
|
|
for (ModuleSpec moduleSpec : viewManagerModuleSpecs) {
|
|
viewManagers.add((ViewManager) moduleSpec.getProvider().get());
|
|
}
|
|
return viewManagers;
|
|
}
|
|
|
|
public abstract ReactModuleInfoProvider getReactModuleInfoProvider();
|
|
}
|