mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-04-11 22:40:37 +08:00
Reviewed By: achen1 Differential Revision: D4317878 fbshipit-source-id: 61ee4b24f0de206f53d6f4b3801d81aa6f3ab36c
155 lines
5.8 KiB
Java
155 lines
5.8 KiB
Java
/**
|
|
* Copyright (c) 2015-present, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*/
|
|
|
|
package com.facebook.react.cxxbridge;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
|
|
import android.util.Pair;
|
|
|
|
import com.facebook.infer.annotation.Assertions;
|
|
import com.facebook.react.bridge.BaseJavaModule;
|
|
import com.facebook.react.bridge.ModuleSpec;
|
|
import com.facebook.react.bridge.NativeModule;
|
|
import com.facebook.react.bridge.OnBatchCompleteListener;
|
|
import com.facebook.react.bridge.ReactMarker;
|
|
import com.facebook.react.bridge.ReactMarkerConstants;
|
|
import com.facebook.react.module.model.ReactModuleInfo;
|
|
import com.facebook.systrace.Systrace;
|
|
|
|
/**
|
|
* A set of Java APIs to expose to a particular JavaScript instance.
|
|
*/
|
|
public class NativeModuleRegistry {
|
|
|
|
private final Map<Class<? extends NativeModule>, ModuleHolder> mModules;
|
|
private final ArrayList<OnBatchCompleteListener> mBatchCompleteListenerModules;
|
|
|
|
public NativeModuleRegistry(
|
|
List<ModuleSpec> moduleSpecList,
|
|
Map<Class, ReactModuleInfo> reactModuleInfoMap,
|
|
boolean isLazyNativeModulesEnabled) {
|
|
Map<String, Pair<Class<? extends NativeModule>, ModuleHolder>> namesToSpecs = new HashMap<>();
|
|
for (ModuleSpec module : moduleSpecList) {
|
|
Class<? extends NativeModule> type = module.getType();
|
|
ReactModuleInfo reactModuleInfo = reactModuleInfoMap.get(type);
|
|
if (isLazyNativeModulesEnabled &&
|
|
reactModuleInfo == null &&
|
|
BaseJavaModule.class.isAssignableFrom(type)) {
|
|
throw new IllegalStateException("Native Java module " + type.getSimpleName() +
|
|
" should be annotated with @ReactModule and added to a @ReactModuleList.");
|
|
}
|
|
ModuleHolder holder = new ModuleHolder(type, reactModuleInfo, module.getProvider());
|
|
String name = holder.getInfo().name();
|
|
Class<? extends NativeModule> existing = namesToSpecs.containsKey(name) ?
|
|
namesToSpecs.get(name).first :
|
|
null;
|
|
if (existing != null && !holder.getInfo().canOverrideExistingModule()) {
|
|
throw new IllegalStateException("Native module " + type.getSimpleName() +
|
|
" tried to override " + existing.getSimpleName() + " for module name " + name +
|
|
". If this was your intention, set canOverrideExistingModule=true");
|
|
}
|
|
namesToSpecs.put(name, new Pair<Class<? extends NativeModule>, ModuleHolder>(type, holder));
|
|
}
|
|
|
|
mModules = new HashMap<>();
|
|
for (Pair<Class<? extends NativeModule>, ModuleHolder> pair : namesToSpecs.values()) {
|
|
mModules.put(pair.first, pair.second);
|
|
}
|
|
|
|
mBatchCompleteListenerModules = new ArrayList<>();
|
|
for (Class<? extends NativeModule> type : mModules.keySet()) {
|
|
if (OnBatchCompleteListener.class.isAssignableFrom(type)) {
|
|
final ModuleHolder holder = mModules.get(type);
|
|
mBatchCompleteListenerModules.add(new OnBatchCompleteListener() {
|
|
@Override
|
|
public void onBatchComplete() {
|
|
OnBatchCompleteListener listener = (OnBatchCompleteListener) holder.getModule();
|
|
listener.onBatchComplete();
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
/* package */ ModuleRegistryHolder getModuleRegistryHolder(
|
|
CatalystInstanceImpl catalystInstanceImpl) {
|
|
ArrayList<JavaModuleWrapper> javaModules = new ArrayList<>();
|
|
ArrayList<CxxModuleWrapper> cxxModules = new ArrayList<>();
|
|
for (Map.Entry<Class<? extends NativeModule>, ModuleHolder> entry : mModules.entrySet()) {
|
|
Class<?> type = entry.getKey();
|
|
ModuleHolder moduleHolder = entry.getValue();
|
|
if (BaseJavaModule.class.isAssignableFrom(type)) {
|
|
javaModules.add(new JavaModuleWrapper(catalystInstanceImpl, moduleHolder));
|
|
} else if (CxxModuleWrapper.class.isAssignableFrom(type)) {
|
|
cxxModules.add((CxxModuleWrapper) moduleHolder.getModule());
|
|
} else {
|
|
throw new IllegalArgumentException("Unknown module type " + type);
|
|
}
|
|
}
|
|
return new ModuleRegistryHolder(catalystInstanceImpl, javaModules, cxxModules);
|
|
}
|
|
|
|
/* package */ void notifyCatalystInstanceDestroy() {
|
|
UiThreadUtil.assertOnUiThread();
|
|
Systrace.beginSection(
|
|
Systrace.TRACE_TAG_REACT_JAVA_BRIDGE,
|
|
"NativeModuleRegistry_notifyCatalystInstanceDestroy");
|
|
try {
|
|
for (ModuleHolder module : mModules.values()) {
|
|
module.destroy();
|
|
}
|
|
} finally {
|
|
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
|
|
}
|
|
}
|
|
|
|
/* package */ void notifyCatalystInstanceInitialized() {
|
|
UiThreadUtil.assertOnUiThread();
|
|
|
|
ReactMarker.logMarker(ReactMarkerConstants.NATIVE_MODULE_INITIALIZE_START);
|
|
Systrace.beginSection(
|
|
Systrace.TRACE_TAG_REACT_JAVA_BRIDGE,
|
|
"NativeModuleRegistry_notifyCatalystInstanceInitialized");
|
|
try {
|
|
for (ModuleHolder module : mModules.values()) {
|
|
module.initialize();
|
|
}
|
|
} finally {
|
|
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
|
|
ReactMarker.logMarker(ReactMarkerConstants.NATIVE_MODULE_INITIALIZE_END);
|
|
}
|
|
}
|
|
|
|
public void onBatchComplete() {
|
|
for (int i = 0; i < mBatchCompleteListenerModules.size(); i++) {
|
|
mBatchCompleteListenerModules.get(i).onBatchComplete();
|
|
}
|
|
}
|
|
|
|
public <T extends NativeModule> boolean hasModule(Class<T> moduleInterface) {
|
|
return mModules.containsKey(moduleInterface);
|
|
}
|
|
|
|
public <T extends NativeModule> T getModule(Class<T> moduleInterface) {
|
|
return (T) Assertions.assertNotNull(mModules.get(moduleInterface)).getModule();
|
|
}
|
|
|
|
public List<NativeModule> getAllModules() {
|
|
List<NativeModule> modules = new ArrayList<>();
|
|
for (ModuleHolder module : mModules.values()) {
|
|
modules.add(module.getModule());
|
|
}
|
|
return modules;
|
|
}
|
|
}
|