mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-02-02 17:18:58 +08:00
This is an early release and there are several things that are known not to work if you're porting your iOS app to Android. See the Known Issues guide on the website. We will work with the community to reach platform parity with iOS.
201 lines
6.7 KiB
Java
201 lines
6.7 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.bridge;
|
|
|
|
import java.io.IOException;
|
|
import java.io.StringWriter;
|
|
import java.util.ArrayList;
|
|
import java.util.Collection;
|
|
import java.util.HashSet;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
|
|
import com.facebook.react.common.MapBuilder;
|
|
import com.facebook.react.common.SetBuilder;
|
|
import com.facebook.infer.annotation.Assertions;
|
|
import com.facebook.systrace.Systrace;
|
|
|
|
import com.fasterxml.jackson.core.JsonFactory;
|
|
import com.fasterxml.jackson.core.JsonGenerator;
|
|
|
|
/**
|
|
* A set of Java APIs to expose to a particular JavaScript instance.
|
|
*/
|
|
public class NativeModuleRegistry {
|
|
|
|
private final ArrayList<ModuleDefinition> mModuleTable;
|
|
private final Map<Class<NativeModule>, NativeModule> mModuleInstances;
|
|
private final String mModuleDescriptions;
|
|
private final ArrayList<OnBatchCompleteListener> mBatchCompleteListenerModules;
|
|
|
|
private NativeModuleRegistry(
|
|
ArrayList<ModuleDefinition> moduleTable,
|
|
Map<Class<NativeModule>, NativeModule> moduleInstances,
|
|
String moduleDescriptions) {
|
|
mModuleTable = moduleTable;
|
|
mModuleInstances = moduleInstances;
|
|
mModuleDescriptions = moduleDescriptions;
|
|
|
|
mBatchCompleteListenerModules = new ArrayList<OnBatchCompleteListener>(mModuleTable.size());
|
|
for (int i = 0; i < mModuleTable.size(); i++) {
|
|
ModuleDefinition definition = mModuleTable.get(i);
|
|
if (definition.target instanceof OnBatchCompleteListener) {
|
|
mBatchCompleteListenerModules.add((OnBatchCompleteListener) definition.target);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* package */ void call(
|
|
CatalystInstance catalystInstance,
|
|
int moduleId,
|
|
int methodId,
|
|
ReadableNativeArray parameters) {
|
|
ModuleDefinition definition = mModuleTable.get(moduleId);
|
|
if (definition == null) {
|
|
throw new RuntimeException("Call to unknown module: " + moduleId);
|
|
}
|
|
definition.call(catalystInstance, methodId, parameters);
|
|
}
|
|
|
|
/* package */ String moduleDescriptions() {
|
|
return mModuleDescriptions;
|
|
}
|
|
|
|
/* package */ void notifyCatalystInstanceDestroy() {
|
|
UiThreadUtil.assertOnUiThread();
|
|
for (NativeModule nativeModule : mModuleInstances.values()) {
|
|
nativeModule.onCatalystInstanceDestroy();
|
|
}
|
|
}
|
|
|
|
/* package */ void notifyCatalystInstanceInitialized() {
|
|
UiThreadUtil.assertOnUiThread();
|
|
for (NativeModule nativeModule : mModuleInstances.values()) {
|
|
nativeModule.initialize();
|
|
}
|
|
}
|
|
|
|
public void onBatchComplete() {
|
|
for (int i = 0; i < mBatchCompleteListenerModules.size(); i++) {
|
|
mBatchCompleteListenerModules.get(i).onBatchComplete();
|
|
}
|
|
}
|
|
|
|
public <T extends NativeModule> T getModule(Class<T> moduleInterface) {
|
|
return (T) Assertions.assertNotNull(mModuleInstances.get(moduleInterface));
|
|
}
|
|
|
|
public Collection<NativeModule> getAllModules() {
|
|
return mModuleInstances.values();
|
|
}
|
|
|
|
private static class ModuleDefinition {
|
|
public final int id;
|
|
public final String name;
|
|
public final NativeModule target;
|
|
public final ArrayList<MethodRegistration> methods;
|
|
|
|
public ModuleDefinition(int id, String name, NativeModule target) {
|
|
this.id = id;
|
|
this.name = name;
|
|
this.target = target;
|
|
this.methods = new ArrayList<MethodRegistration>();
|
|
|
|
for (Map.Entry<String, NativeModule.NativeMethod> entry : target.getMethods().entrySet()) {
|
|
this.methods.add(
|
|
new MethodRegistration(
|
|
entry.getKey(), "NativeCall__" + target.getName() + "_" + entry.getKey(),
|
|
entry.getValue()));
|
|
}
|
|
}
|
|
|
|
public void call(
|
|
CatalystInstance catalystInstance,
|
|
int methodId,
|
|
ReadableNativeArray parameters) {
|
|
MethodRegistration method = this.methods.get(methodId);
|
|
Systrace.beginSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, method.tracingName);
|
|
try {
|
|
this.methods.get(methodId).method.invoke(catalystInstance, parameters);
|
|
} finally {
|
|
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
|
|
}
|
|
}
|
|
}
|
|
|
|
private static class MethodRegistration {
|
|
public MethodRegistration(String name, String tracingName, NativeModule.NativeMethod method) {
|
|
this.name = name;
|
|
this.tracingName = tracingName;
|
|
this.method = method;
|
|
}
|
|
|
|
public String name;
|
|
public String tracingName;
|
|
public NativeModule.NativeMethod method;
|
|
}
|
|
|
|
public static class Builder {
|
|
|
|
private ArrayList<ModuleDefinition> mModuleDefinitions;
|
|
private Map<Class<NativeModule>, NativeModule> mModuleInstances;
|
|
private Set<String> mSeenModuleNames;
|
|
|
|
public Builder() {
|
|
mModuleDefinitions = new ArrayList<ModuleDefinition>();
|
|
mModuleInstances = MapBuilder.newHashMap();
|
|
mSeenModuleNames = SetBuilder.newHashSet();
|
|
}
|
|
|
|
public Builder add(NativeModule module) {
|
|
ModuleDefinition registration = new ModuleDefinition(
|
|
mModuleDefinitions.size(),
|
|
module.getName(),
|
|
module);
|
|
Assertions.assertCondition(
|
|
!mSeenModuleNames.contains(module.getName()),
|
|
"Module " + module.getName() + " was already registered!");
|
|
mSeenModuleNames.add(module.getName());
|
|
mModuleDefinitions.add(registration);
|
|
mModuleInstances.put((Class<NativeModule>) module.getClass(), module);
|
|
return this;
|
|
}
|
|
|
|
public NativeModuleRegistry build() {
|
|
JsonFactory jsonFactory = new JsonFactory();
|
|
StringWriter writer = new StringWriter();
|
|
try {
|
|
JsonGenerator jg = jsonFactory.createGenerator(writer);
|
|
jg.writeStartObject();
|
|
for (ModuleDefinition module : mModuleDefinitions) {
|
|
jg.writeObjectFieldStart(module.name);
|
|
jg.writeNumberField("moduleID", module.id);
|
|
jg.writeObjectFieldStart("methods");
|
|
for (int i = 0; i < module.methods.size(); i++) {
|
|
MethodRegistration method = module.methods.get(i);
|
|
jg.writeObjectFieldStart(method.name);
|
|
jg.writeNumberField("methodID", i);
|
|
jg.writeEndObject();
|
|
}
|
|
jg.writeEndObject();
|
|
module.target.writeConstantsField(jg, "constants");
|
|
jg.writeEndObject();
|
|
}
|
|
jg.writeEndObject();
|
|
jg.close();
|
|
} catch (IOException ioe) {
|
|
throw new RuntimeException("Unable to serialize Java module configuration", ioe);
|
|
}
|
|
String moduleDefinitionJson = writer.getBuffer().toString();
|
|
return new NativeModuleRegistry(mModuleDefinitions, mModuleInstances, moduleDefinitionJson);
|
|
}
|
|
}
|
|
}
|