mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-04-16 23:00:20 +08:00
Merge ReactMethod and ReactSyncHook
Reviewed By: astreet Differential Revision: D4409726 fbshipit-source-id: 7a0091da754b114680772aa9c0a898b1aa721ba5
This commit is contained in:
committed by
Facebook Github Bot
parent
412acd237a
commit
59226f022c
@@ -176,12 +176,18 @@ public abstract class BaseJavaModule implements NativeModule {
|
||||
private final int mJSArgumentsNeeded;
|
||||
private final String mTraceName;
|
||||
|
||||
public JavaMethod(Method method) {
|
||||
public JavaMethod(Method method, boolean isSync) {
|
||||
mMethod = method;
|
||||
mMethod.setAccessible(true);
|
||||
|
||||
if (isSync) {
|
||||
mType = METHOD_TYPE_SYNC;
|
||||
}
|
||||
|
||||
// TODO: create these lazily
|
||||
Class[] parameterTypes = method.getParameterTypes();
|
||||
mArgumentExtractors = buildArgumentExtractors(parameterTypes);
|
||||
mSignature = buildSignature(parameterTypes);
|
||||
mSignature = buildSignature(mMethod, parameterTypes, isSync);
|
||||
// Since native methods are invoked from a message queue executed on a single thread, it is
|
||||
// save to allocate only one arguments object per method that can be reused across calls
|
||||
mArguments = new Object[parameterTypes.length];
|
||||
@@ -197,9 +203,16 @@ public abstract class BaseJavaModule implements NativeModule {
|
||||
return mSignature;
|
||||
}
|
||||
|
||||
private String buildSignature(Class[] paramTypes) {
|
||||
StringBuilder builder = new StringBuilder(paramTypes.length);
|
||||
builder.append("v.");
|
||||
private String buildSignature(Method method, Class[] paramTypes, boolean isSync) {
|
||||
StringBuilder builder = new StringBuilder(paramTypes.length + 2);
|
||||
|
||||
if (isSync) {
|
||||
builder.append(returnTypeToChar(method.getReturnType()));
|
||||
builder.append('.');
|
||||
} else {
|
||||
builder.append("v.");
|
||||
}
|
||||
|
||||
for (int i = 0; i < paramTypes.length; i++) {
|
||||
Class paramClass = paramTypes[i];
|
||||
if (paramClass == ExecutorToken.class) {
|
||||
@@ -212,7 +225,9 @@ public abstract class BaseJavaModule implements NativeModule {
|
||||
} else if (paramClass == Promise.class) {
|
||||
Assertions.assertCondition(
|
||||
i == paramTypes.length - 1, "Promise must be used as last parameter only");
|
||||
mType = METHOD_TYPE_PROMISE;
|
||||
if (!isSync) {
|
||||
mType = METHOD_TYPE_PROMISE;
|
||||
}
|
||||
}
|
||||
builder.append(paramTypeToChar(paramClass));
|
||||
}
|
||||
@@ -352,6 +367,7 @@ public abstract class BaseJavaModule implements NativeModule {
|
||||
* Determines how the method is exported in JavaScript:
|
||||
* METHOD_TYPE_ASYNC for regular methods
|
||||
* METHOD_TYPE_PROMISE for methods that return a promise object to the caller.
|
||||
* METHOD_TYPE_SYNC for sync methods
|
||||
*/
|
||||
@Override
|
||||
public String getType() {
|
||||
@@ -359,82 +375,28 @@ public abstract class BaseJavaModule implements NativeModule {
|
||||
}
|
||||
}
|
||||
|
||||
public class SyncJavaHook implements SyncNativeHook {
|
||||
|
||||
private Method mMethod;
|
||||
private final String mSignature;
|
||||
|
||||
public SyncJavaHook(Method method) {
|
||||
mMethod = method;
|
||||
mMethod.setAccessible(true);
|
||||
mSignature = buildSignature(method);
|
||||
}
|
||||
|
||||
public Method getMethod() {
|
||||
return mMethod;
|
||||
}
|
||||
|
||||
public String getSignature() {
|
||||
return mSignature;
|
||||
}
|
||||
|
||||
private String buildSignature(Method method) {
|
||||
Class[] paramTypes = method.getParameterTypes();
|
||||
StringBuilder builder = new StringBuilder(paramTypes.length + 2);
|
||||
|
||||
builder.append(returnTypeToChar(method.getReturnType()));
|
||||
builder.append('.');
|
||||
|
||||
for (int i = 0; i < paramTypes.length; i++) {
|
||||
Class paramClass = paramTypes[i];
|
||||
if (paramClass == ExecutorToken.class) {
|
||||
if (!BaseJavaModule.this.supportsWebWorkers()) {
|
||||
throw new RuntimeException(
|
||||
"Module " + BaseJavaModule.this + " doesn't support web workers, but " +
|
||||
mMethod.getName() +
|
||||
" takes an ExecutorToken.");
|
||||
}
|
||||
} else if (paramClass == Promise.class) {
|
||||
Assertions.assertCondition(
|
||||
i == paramTypes.length - 1, "Promise must be used as last parameter only");
|
||||
}
|
||||
builder.append(paramTypeToChar(paramClass));
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
|
||||
private @Nullable Map<String, NativeMethod> mMethods;
|
||||
private @Nullable Map<String, SyncNativeHook> mHooks;
|
||||
|
||||
private void findMethods() {
|
||||
if (mMethods == null) {
|
||||
Systrace.beginSection(TRACE_TAG_REACT_JAVA_BRIDGE, "findMethods");
|
||||
mMethods = new HashMap<>();
|
||||
mHooks = new HashMap<>();
|
||||
|
||||
Method[] targetMethods = getClass().getDeclaredMethods();
|
||||
for (Method targetMethod : targetMethods) {
|
||||
if (targetMethod.getAnnotation(ReactMethod.class) != null) {
|
||||
ReactMethod annotation = targetMethod.getAnnotation(ReactMethod.class);
|
||||
if (annotation != null) {
|
||||
String methodName = targetMethod.getName();
|
||||
if (mHooks.containsKey(methodName) || mMethods.containsKey(methodName)) {
|
||||
if (mMethods.containsKey(methodName)) {
|
||||
// We do not support method overloading since js sees a function as an object regardless
|
||||
// of number of params.
|
||||
throw new IllegalArgumentException(
|
||||
"Java Module " + getName() + " sync method name already registered: " + methodName);
|
||||
"Java Module " + getName() + " method name already registered: " + methodName);
|
||||
}
|
||||
mMethods.put(methodName, new JavaMethod(targetMethod));
|
||||
}
|
||||
if (targetMethod.getAnnotation(ReactSyncHook.class) != null) {
|
||||
String methodName = targetMethod.getName();
|
||||
if (mHooks.containsKey(methodName) || mMethods.containsKey(methodName)) {
|
||||
// We do not support method overloading since js sees a function as an object regardless
|
||||
// of number of params.
|
||||
throw new IllegalArgumentException(
|
||||
"Java Module " + getName() + " sync method name already registered: " + methodName);
|
||||
}
|
||||
mHooks.put(methodName, new SyncJavaHook(targetMethod));
|
||||
mMethods.put(
|
||||
methodName,
|
||||
new JavaMethod(targetMethod,
|
||||
annotation.isBlockingSynchronousMethod()));
|
||||
}
|
||||
}
|
||||
Systrace.endSection(TRACE_TAG_REACT_JAVA_BRIDGE);
|
||||
@@ -454,11 +416,6 @@ public abstract class BaseJavaModule implements NativeModule {
|
||||
return null;
|
||||
}
|
||||
|
||||
public final Map<String, SyncNativeHook> getSyncHooks() {
|
||||
findMethods();
|
||||
return assertNotNull(mHooks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
// do nothing
|
||||
|
||||
Reference in New Issue
Block a user