mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-02-01 09:08:47 +08:00
Summary: public Adds useful systrace perf markers for cold start analysis Reviewed By: mikearmstrong001 Differential Revision: D2695629 fb-gh-sync-id: d964f28a1f3e10a13c441a17b0300c980d4914e8
224 lines
7.5 KiB
Java
224 lines
7.5 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.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();
|
|
Systrace.beginSection(
|
|
Systrace.TRACE_TAG_REACT_JAVA_BRIDGE,
|
|
"NativeModuleRegistry_notifyCatalystInstanceDestroy");
|
|
try {
|
|
for (NativeModule nativeModule : mModuleInstances.values()) {
|
|
nativeModule.onCatalystInstanceDestroy();
|
|
}
|
|
} finally {
|
|
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
|
|
}
|
|
}
|
|
|
|
/* package */ void notifyCatalystInstanceInitialized() {
|
|
UiThreadUtil.assertOnUiThread();
|
|
|
|
ReactMarker.logMarker("NativeModule_start");
|
|
Systrace.beginSection(
|
|
Systrace.TRACE_TAG_REACT_JAVA_BRIDGE,
|
|
"NativeModuleRegistry_notifyCatalystInstanceInitialized");
|
|
try {
|
|
for (NativeModule nativeModule : mModuleInstances.values()) {
|
|
nativeModule.initialize();
|
|
}
|
|
} finally {
|
|
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
|
|
ReactMarker.logMarker("NativeModule_end");
|
|
}
|
|
}
|
|
|
|
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() {
|
|
Systrace.beginSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "CreateJSON");
|
|
String moduleDefinitionJson;
|
|
try {
|
|
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.writeStringField("type", method.method.getType());
|
|
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);
|
|
}
|
|
moduleDefinitionJson = writer.getBuffer().toString();
|
|
} finally {
|
|
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
|
|
}
|
|
return new NativeModuleRegistry(mModuleDefinitions, mModuleInstances, moduleDefinitionJson);
|
|
}
|
|
}
|
|
}
|