mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-04-08 17:46:35 +08:00
Drop support for webworkers
Reviewed By: AaaChiuuu Differential Revision: D4916449 fbshipit-source-id: a447233d3b7cfee98db2ce00f1c0505d513e2429
This commit is contained in:
committed by
Facebook Github Bot
parent
a20882f62e
commit
34bc6bd2ae
@@ -42,7 +42,6 @@ import com.facebook.react.bridge.ReactMarker;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.bridge.WritableNativeMap;
|
||||
import com.facebook.react.bridge.queue.ReactQueueConfigurationSpec;
|
||||
import com.facebook.react.common.ApplicationHolder;
|
||||
import com.facebook.react.common.LifecycleState;
|
||||
import com.facebook.react.common.ReactConstants;
|
||||
import com.facebook.react.common.annotations.VisibleForTesting;
|
||||
@@ -229,8 +228,6 @@ public class ReactInstanceManager {
|
||||
|
||||
initializeSoLoaderIfNecessary(applicationContext);
|
||||
|
||||
// TODO(9577825): remove this
|
||||
ApplicationHolder.setApplication((Application) applicationContext.getApplicationContext());
|
||||
DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(applicationContext);
|
||||
|
||||
mApplicationContext = applicationContext;
|
||||
|
||||
@@ -66,11 +66,6 @@ public abstract class BaseJavaModule implements NativeModule {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsWebWorkers() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean hasConstants() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -15,13 +15,11 @@ package com.facebook.react.bridge;
|
||||
public final class CallbackImpl implements Callback {
|
||||
|
||||
private final JSInstance mJSInstance;
|
||||
private final ExecutorToken mExecutorToken;
|
||||
private final int mCallbackId;
|
||||
private boolean mInvoked;
|
||||
|
||||
public CallbackImpl(JSInstance jsInstance, ExecutorToken executorToken, int callbackId) {
|
||||
public CallbackImpl(JSInstance jsInstance, int callbackId) {
|
||||
mJSInstance = jsInstance;
|
||||
mExecutorToken = executorToken;
|
||||
mCallbackId = callbackId;
|
||||
mInvoked = false;
|
||||
}
|
||||
@@ -33,7 +31,7 @@ public final class CallbackImpl implements Callback {
|
||||
"module. This callback type only permits a single invocation from "+
|
||||
"native code.");
|
||||
}
|
||||
mJSInstance.invokeCallback(mExecutorToken, mCallbackId, Arguments.fromJavaArgs(args));
|
||||
mJSInstance.invokeCallback(mCallbackId, Arguments.fromJavaArgs(args));
|
||||
mInvoked = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,12 +37,10 @@ public interface CatalystInstance
|
||||
// which this prevents.
|
||||
@Override @DoNotStrip
|
||||
void invokeCallback(
|
||||
ExecutorToken executorToken,
|
||||
int callbackID,
|
||||
NativeArray arguments);
|
||||
@DoNotStrip
|
||||
void callFunction(
|
||||
ExecutorToken executorToken,
|
||||
String module,
|
||||
String method,
|
||||
NativeArray arguments);
|
||||
@@ -63,7 +61,6 @@ public interface CatalystInstance
|
||||
ReactQueueConfiguration getReactQueueConfiguration();
|
||||
|
||||
<T extends JavaScriptModule> T getJSModule(Class<T> jsInterface);
|
||||
<T extends JavaScriptModule> T getJSModule(ExecutorToken executorToken, Class<T> jsInterface);
|
||||
<T extends NativeModule> boolean hasNativeModule(Class<T> nativeModuleInterface);
|
||||
<T extends NativeModule> T getNativeModule(Class<T> nativeModuleInterface);
|
||||
Collection<NativeModule> getNativeModules();
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
package com.facebook.react.bridge;
|
||||
|
||||
import com.facebook.jni.HybridData;
|
||||
import com.facebook.proguard.annotations.DoNotStrip;
|
||||
|
||||
/**
|
||||
* Class corresponding to a JS VM that can call into native modules. In Java, this should
|
||||
* just be treated as a black box to be used to help the framework route native->JS calls back to
|
||||
* the proper JS VM. See {@link ReactContext#getJSModule(ExecutorToken, Class)} and
|
||||
* {@link BaseJavaModule#supportsWebWorkers()}.
|
||||
*
|
||||
* Note: If your application doesn't use web workers, it will only have a single ExecutorToken
|
||||
* per instance of React Native.
|
||||
*/
|
||||
@DoNotStrip
|
||||
public class ExecutorToken {
|
||||
|
||||
private final HybridData mHybridData;
|
||||
|
||||
@DoNotStrip
|
||||
private ExecutorToken(HybridData hybridData) {
|
||||
mHybridData = hybridData;
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,6 @@ package com.facebook.react.bridge;
|
||||
*/
|
||||
public interface JSInstance {
|
||||
void invokeCallback(
|
||||
ExecutorToken executorToken,
|
||||
int callbackID,
|
||||
NativeArray arguments);
|
||||
// TODO if this interface survives refactoring, think about adding
|
||||
|
||||
@@ -31,11 +31,11 @@ import com.facebook.react.common.ReactConstants;
|
||||
* JavaScript.
|
||||
*/
|
||||
public class JavaScriptModuleRegistry {
|
||||
private final WeakHashMap<ExecutorToken, HashMap<Class<? extends JavaScriptModule>, JavaScriptModule>> mModuleInstances;
|
||||
private final HashMap<Class<? extends JavaScriptModule>, JavaScriptModule> mModuleInstances;
|
||||
private final HashMap<Class<? extends JavaScriptModule>, JavaScriptModuleRegistration> mModuleRegistrations;
|
||||
|
||||
public JavaScriptModuleRegistry(List<JavaScriptModuleRegistration> config) {
|
||||
mModuleInstances = new WeakHashMap<>();
|
||||
mModuleInstances = new HashMap<>();
|
||||
mModuleRegistrations = new HashMap<>();
|
||||
for (JavaScriptModuleRegistration registration : config) {
|
||||
mModuleRegistrations.put(registration.getModuleInterface(), registration);
|
||||
@@ -43,17 +43,9 @@ public class JavaScriptModuleRegistry {
|
||||
}
|
||||
|
||||
public synchronized <T extends JavaScriptModule> T getJavaScriptModule(
|
||||
CatalystInstance instance,
|
||||
ExecutorToken executorToken,
|
||||
Class<T> moduleInterface) {
|
||||
HashMap<Class<? extends JavaScriptModule>, JavaScriptModule> instancesForContext =
|
||||
mModuleInstances.get(executorToken);
|
||||
if (instancesForContext == null) {
|
||||
instancesForContext = new HashMap<>();
|
||||
mModuleInstances.put(executorToken, instancesForContext);
|
||||
}
|
||||
|
||||
JavaScriptModule module = instancesForContext.get(moduleInterface);
|
||||
CatalystInstance instance,
|
||||
Class<T> moduleInterface) {
|
||||
JavaScriptModule module = mModuleInstances.get(moduleInterface);
|
||||
if (module != null) {
|
||||
return (T) module;
|
||||
}
|
||||
@@ -65,8 +57,8 @@ public class JavaScriptModuleRegistry {
|
||||
JavaScriptModule interfaceProxy = (JavaScriptModule) Proxy.newProxyInstance(
|
||||
moduleInterface.getClassLoader(),
|
||||
new Class[]{moduleInterface},
|
||||
new JavaScriptModuleInvocationHandler(executorToken, instance, registration));
|
||||
instancesForContext.put(moduleInterface, interfaceProxy);
|
||||
new JavaScriptModuleInvocationHandler(instance, registration));
|
||||
mModuleInstances.put(moduleInterface, interfaceProxy);
|
||||
return (T) interfaceProxy;
|
||||
}
|
||||
|
||||
@@ -85,30 +77,20 @@ public class JavaScriptModuleRegistry {
|
||||
}
|
||||
|
||||
private static class JavaScriptModuleInvocationHandler implements InvocationHandler {
|
||||
|
||||
private final WeakReference<ExecutorToken> mExecutorToken;
|
||||
private final CatalystInstance mCatalystInstance;
|
||||
private final JavaScriptModuleRegistration mModuleRegistration;
|
||||
|
||||
public JavaScriptModuleInvocationHandler(
|
||||
ExecutorToken executorToken,
|
||||
CatalystInstance catalystInstance,
|
||||
JavaScriptModuleRegistration moduleRegistration) {
|
||||
mExecutorToken = new WeakReference<>(executorToken);
|
||||
mCatalystInstance = catalystInstance;
|
||||
mModuleRegistration = moduleRegistration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Object invoke(Object proxy, Method method, @Nullable Object[] args) throws Throwable {
|
||||
ExecutorToken executorToken = mExecutorToken.get();
|
||||
if (executorToken == null) {
|
||||
FLog.w(ReactConstants.TAG, "Dropping JS call, ExecutorToken went away...");
|
||||
return null;
|
||||
}
|
||||
NativeArray jsArgs = args != null ? Arguments.fromJavaArgs(args) : new WritableNativeArray();
|
||||
mCatalystInstance.callFunction(
|
||||
executorToken,
|
||||
mModuleRegistration.getName(),
|
||||
method.getName(),
|
||||
jsArgs
|
||||
|
||||
@@ -9,10 +9,7 @@
|
||||
|
||||
package com.facebook.react.bridge;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A native module whose API can be provided to JS catalyst instances. {@link NativeModule}s whose
|
||||
@@ -23,7 +20,7 @@ import java.util.Map;
|
||||
*/
|
||||
public interface NativeModule {
|
||||
interface NativeMethod {
|
||||
void invoke(JSInstance jsInstance, ExecutorToken executorToken, ReadableNativeArray parameters);
|
||||
void invoke(JSInstance jsInstance, ReadableNativeArray parameters);
|
||||
String getType();
|
||||
}
|
||||
|
||||
@@ -52,27 +49,4 @@ public interface NativeModule {
|
||||
* Called before {CatalystInstance#onHostDestroy}
|
||||
*/
|
||||
void onCatalystInstanceDestroy();
|
||||
|
||||
/**
|
||||
* In order to support web workers, a module must be aware that it can be invoked from multiple
|
||||
* different JS VMs. Supporting web workers means recognizing things like:
|
||||
*
|
||||
* 1) ids (e.g. timer ids, request ids, etc.) may only unique on a per-VM basis
|
||||
* 2) the module needs to make sure to enqueue callbacks and JS module calls to the correct VM
|
||||
*
|
||||
* In order to facilitate this, modules that support web workers will have all their @ReactMethod-
|
||||
* annotated methods passed a {@link ExecutorToken} as the first parameter before any arguments
|
||||
* from JS. This ExecutorToken internally maps to a specific JS VM and can be used by the
|
||||
* framework to route calls appropriately. In order to make JS module calls correctly, start using
|
||||
* the version of {@link ReactContext#getJSModule(ExecutorToken, Class)} that takes an
|
||||
* ExecutorToken. It will ensure that any calls you dispatch to the returned object will go to
|
||||
* the right VM. For Callbacks, you don't have to do anything special -- the framework
|
||||
* automatically tags them with the correct ExecutorToken when the are created.
|
||||
*
|
||||
* Note: even though calls can come from multiple JS VMs on multiple threads, calls to this module
|
||||
* will still only occur on a single thread.
|
||||
*
|
||||
* @return whether this module supports web workers.
|
||||
*/
|
||||
boolean supportsWebWorkers();
|
||||
}
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Interface for a module that will be notified when JS executors have been unregistered from the bridge.
|
||||
* Note that this will NOT notify listeners about the main executor being destroyed: use
|
||||
* {@link NativeModule#onCatalystInstanceDestroy()} for that. Once a module has received a
|
||||
* {@link NativeModule#onCatalystInstanceDestroy()} call, it will not receive any onExecutorUnregistered
|
||||
* calls.
|
||||
*/
|
||||
public interface OnExecutorUnregisteredListener {
|
||||
|
||||
void onExecutorDestroyed(ExecutorToken executorToken);
|
||||
}
|
||||
@@ -107,15 +107,6 @@ public class ReactContext extends ContextWrapper {
|
||||
return mCatalystInstance.getJSModule(jsInterface);
|
||||
}
|
||||
|
||||
public <T extends JavaScriptModule> T getJSModule(
|
||||
ExecutorToken executorToken,
|
||||
Class<T> jsInterface) {
|
||||
if (mCatalystInstance == null) {
|
||||
throw new RuntimeException(EARLY_JS_ACCESS_EXCEPTION_MESSAGE);
|
||||
}
|
||||
return mCatalystInstance.getJSModule(executorToken, jsInterface);
|
||||
}
|
||||
|
||||
public <T extends NativeModule> boolean hasNativeModule(Class<T> nativeModuleInterface) {
|
||||
if (mCatalystInstance == null) {
|
||||
throw new RuntimeException(
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
// Copyright 2004-present Facebook. All Rights Reserved.
|
||||
|
||||
package com.facebook.react.bridge;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
/**
|
||||
* Annotation indicating that a JS module should be made available to web
|
||||
* workers spawned by the main JS executor.
|
||||
*/
|
||||
@Retention(RUNTIME)
|
||||
public @interface SupportsWebWorkers {
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/**
|
||||
* 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.common;
|
||||
|
||||
import android.app.Application;
|
||||
|
||||
import com.facebook.infer.annotation.Assertions;
|
||||
import com.facebook.proguard.annotations.DoNotStrip;
|
||||
|
||||
/**
|
||||
* Holds the current Application Object.
|
||||
*
|
||||
* TODO(9577825): This is a bad pattern, we should thread through an Environment object instead.
|
||||
* Remove once bridge is unforked.
|
||||
*/
|
||||
@DoNotStrip
|
||||
@Deprecated
|
||||
public class ApplicationHolder {
|
||||
|
||||
private static Application sApplication;
|
||||
|
||||
public static void setApplication(Application application) {
|
||||
sApplication = application;
|
||||
}
|
||||
|
||||
@DoNotStrip
|
||||
public static Application getApplication() {
|
||||
return Assertions.assertNotNull(sApplication);
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,6 @@ import com.facebook.infer.annotation.Assertions;
|
||||
import com.facebook.jni.HybridData;
|
||||
import com.facebook.proguard.annotations.DoNotStrip;
|
||||
import com.facebook.react.bridge.CatalystInstance;
|
||||
import com.facebook.react.bridge.ExecutorToken;
|
||||
import com.facebook.react.bridge.JavaScriptModule;
|
||||
import com.facebook.react.bridge.JavaScriptModuleRegistry;
|
||||
import com.facebook.react.bridge.MemoryPressure;
|
||||
@@ -60,17 +59,14 @@ public class CatalystInstanceImpl implements CatalystInstance {
|
||||
|
||||
private static class PendingJSCall {
|
||||
|
||||
public ExecutorToken mExecutorToken;
|
||||
public String mModule;
|
||||
public String mMethod;
|
||||
public NativeArray mArguments;
|
||||
|
||||
public PendingJSCall(
|
||||
ExecutorToken executorToken,
|
||||
String module,
|
||||
String method,
|
||||
NativeArray arguments) {
|
||||
mExecutorToken = executorToken;
|
||||
mModule = module;
|
||||
mMethod = method;
|
||||
mArguments = arguments;
|
||||
@@ -89,7 +85,6 @@ public class CatalystInstanceImpl implements CatalystInstance {
|
||||
private final JSBundleLoader mJSBundleLoader;
|
||||
private final ArrayList<PendingJSCall> mJSCallsPendingInit = new ArrayList<PendingJSCall>();
|
||||
private final Object mJSCallsPendingInitLock = new Object();
|
||||
private ExecutorToken mMainExecutorToken;
|
||||
|
||||
private final NativeModuleRegistry mJavaRegistry;
|
||||
private final NativeModuleCallExceptionHandler mNativeModuleCallExceptionHandler;
|
||||
@@ -134,7 +129,6 @@ public class CatalystInstanceImpl implements CatalystInstance {
|
||||
mJavaRegistry.getJavaModules(this),
|
||||
mJavaRegistry.getCxxModules());
|
||||
FLog.d(ReactConstants.TAG, "Initializing React Xplat Bridge after initializeBridge");
|
||||
mMainExecutorToken = getMainExecutorToken();
|
||||
}
|
||||
|
||||
private static class BridgeCallback implements ReactCallback {
|
||||
@@ -224,7 +218,7 @@ public class CatalystInstanceImpl implements CatalystInstance {
|
||||
mAcceptCalls = true;
|
||||
|
||||
for (PendingJSCall call : mJSCallsPendingInit) {
|
||||
jniCallJSFunction(call.mExecutorToken, call.mModule, call.mMethod, call.mArguments);
|
||||
jniCallJSFunction(call.mModule, call.mMethod, call.mArguments);
|
||||
}
|
||||
mJSCallsPendingInit.clear();
|
||||
}
|
||||
@@ -239,14 +233,12 @@ public class CatalystInstanceImpl implements CatalystInstance {
|
||||
}
|
||||
|
||||
private native void jniCallJSFunction(
|
||||
ExecutorToken token,
|
||||
String module,
|
||||
String method,
|
||||
NativeArray arguments);
|
||||
|
||||
@Override
|
||||
public void callFunction(
|
||||
ExecutorToken executorToken,
|
||||
final String module,
|
||||
final String method,
|
||||
final NativeArray arguments) {
|
||||
@@ -258,25 +250,25 @@ public class CatalystInstanceImpl implements CatalystInstance {
|
||||
// Most of the time the instance is initialized and we don't need to acquire the lock
|
||||
synchronized (mJSCallsPendingInitLock) {
|
||||
if (!mAcceptCalls) {
|
||||
mJSCallsPendingInit.add(new PendingJSCall(executorToken, module, method, arguments));
|
||||
mJSCallsPendingInit.add(new PendingJSCall(module, method, arguments));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
jniCallJSFunction(executorToken, module, method, arguments);
|
||||
jniCallJSFunction(module, method, arguments);
|
||||
}
|
||||
|
||||
private native void jniCallJSCallback(ExecutorToken executorToken, int callbackID, NativeArray arguments);
|
||||
private native void jniCallJSCallback(int callbackID, NativeArray arguments);
|
||||
|
||||
@Override
|
||||
public void invokeCallback(ExecutorToken executorToken, final int callbackID, final NativeArray arguments) {
|
||||
public void invokeCallback(final int callbackID, final NativeArray arguments) {
|
||||
if (mDestroyed) {
|
||||
FLog.w(ReactConstants.TAG, "Invoking JS callback after bridge has been destroyed.");
|
||||
return;
|
||||
}
|
||||
|
||||
jniCallJSCallback(executorToken, callbackID, arguments);
|
||||
jniCallJSCallback(callbackID, arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -348,17 +340,9 @@ public class CatalystInstanceImpl implements CatalystInstance {
|
||||
|
||||
@Override
|
||||
public <T extends JavaScriptModule> T getJSModule(Class<T> jsInterface) {
|
||||
return getJSModule(mMainExecutorToken, jsInterface);
|
||||
return mJSModuleRegistry.getJavaScriptModule(this, jsInterface);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends JavaScriptModule> T getJSModule(ExecutorToken executorToken, Class<T> jsInterface) {
|
||||
return Assertions.assertNotNull(mJSModuleRegistry)
|
||||
.getJavaScriptModule(this, executorToken, jsInterface);
|
||||
}
|
||||
|
||||
private native ExecutorToken getMainExecutorToken();
|
||||
|
||||
@Override
|
||||
public <T extends NativeModule> boolean hasNativeModule(Class<T> nativeModuleInterface) {
|
||||
return mJavaRegistry.hasModule(nativeModuleInterface);
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
package com.facebook.react.cxxbridge;
|
||||
|
||||
|
||||
import com.facebook.jni.HybridData;
|
||||
import com.facebook.proguard.annotations.DoNotStrip;
|
||||
import com.facebook.react.bridge.NativeModule;
|
||||
@@ -37,11 +36,6 @@ public class CxxModuleWrapperBase implements NativeModule
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsWebWorkers() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCatalystInstanceDestroy() {
|
||||
mHybridData.resetNative();
|
||||
|
||||
@@ -14,11 +14,22 @@ import javax.annotation.Nullable;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import com.facebook.react.bridge.*;
|
||||
|
||||
import com.facebook.infer.annotation.Assertions;
|
||||
import com.facebook.react.cxxbridge.JavaModuleWrapper;
|
||||
import com.facebook.systrace.Systrace;
|
||||
import com.facebook.react.bridge.BaseJavaModule;
|
||||
import com.facebook.react.bridge.Callback;
|
||||
import com.facebook.react.bridge.Dynamic;
|
||||
import com.facebook.react.bridge.DynamicFromArray;
|
||||
import com.facebook.react.bridge.JSInstance;
|
||||
import com.facebook.react.bridge.NativeArgumentsParseException;
|
||||
import com.facebook.react.bridge.NativeModule;
|
||||
import com.facebook.react.bridge.Promise;
|
||||
import com.facebook.react.bridge.PromiseImpl;
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.bridge.ReadableNativeArray;
|
||||
import com.facebook.react.bridge.UnexpectedNativeTypeException;
|
||||
import com.facebook.react.bridge.WritableArray;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.systrace.SystraceMessage;
|
||||
|
||||
import static com.facebook.infer.annotation.Assertions.assertNotNull;
|
||||
@@ -32,14 +43,14 @@ public class JavaMethodWrapper implements NativeModule.NativeMethod {
|
||||
}
|
||||
|
||||
public abstract @Nullable T extractArgument(
|
||||
JSInstance jsInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex);
|
||||
JSInstance jsInstance, ReadableNativeArray jsArguments, int atIndex);
|
||||
}
|
||||
|
||||
static final private ArgumentExtractor<Boolean> ARGUMENT_EXTRACTOR_BOOLEAN =
|
||||
new ArgumentExtractor<Boolean>() {
|
||||
@Override
|
||||
public Boolean extractArgument(
|
||||
JSInstance jsInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) {
|
||||
JSInstance jsInstance, ReadableNativeArray jsArguments, int atIndex) {
|
||||
return jsArguments.getBoolean(atIndex);
|
||||
}
|
||||
};
|
||||
@@ -48,7 +59,7 @@ public class JavaMethodWrapper implements NativeModule.NativeMethod {
|
||||
new ArgumentExtractor<Double>() {
|
||||
@Override
|
||||
public Double extractArgument(
|
||||
JSInstance jsInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) {
|
||||
JSInstance jsInstance, ReadableNativeArray jsArguments, int atIndex) {
|
||||
return jsArguments.getDouble(atIndex);
|
||||
}
|
||||
};
|
||||
@@ -57,7 +68,7 @@ public class JavaMethodWrapper implements NativeModule.NativeMethod {
|
||||
new ArgumentExtractor<Float>() {
|
||||
@Override
|
||||
public Float extractArgument(
|
||||
JSInstance jsInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) {
|
||||
JSInstance jsInstance, ReadableNativeArray jsArguments, int atIndex) {
|
||||
return (float) jsArguments.getDouble(atIndex);
|
||||
}
|
||||
};
|
||||
@@ -66,7 +77,7 @@ public class JavaMethodWrapper implements NativeModule.NativeMethod {
|
||||
new ArgumentExtractor<Integer>() {
|
||||
@Override
|
||||
public Integer extractArgument(
|
||||
JSInstance jsInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) {
|
||||
JSInstance jsInstance, ReadableNativeArray jsArguments, int atIndex) {
|
||||
return (int) jsArguments.getDouble(atIndex);
|
||||
}
|
||||
};
|
||||
@@ -75,7 +86,7 @@ public class JavaMethodWrapper implements NativeModule.NativeMethod {
|
||||
new ArgumentExtractor<String>() {
|
||||
@Override
|
||||
public String extractArgument(
|
||||
JSInstance jsInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) {
|
||||
JSInstance jsInstance, ReadableNativeArray jsArguments, int atIndex) {
|
||||
return jsArguments.getString(atIndex);
|
||||
}
|
||||
};
|
||||
@@ -84,7 +95,7 @@ public class JavaMethodWrapper implements NativeModule.NativeMethod {
|
||||
new ArgumentExtractor<ReadableNativeArray>() {
|
||||
@Override
|
||||
public ReadableNativeArray extractArgument(
|
||||
JSInstance jsInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) {
|
||||
JSInstance jsInstance, ReadableNativeArray jsArguments, int atIndex) {
|
||||
return jsArguments.getArray(atIndex);
|
||||
}
|
||||
};
|
||||
@@ -93,7 +104,7 @@ public class JavaMethodWrapper implements NativeModule.NativeMethod {
|
||||
new ArgumentExtractor<Dynamic>() {
|
||||
@Override
|
||||
public Dynamic extractArgument(
|
||||
JSInstance jsInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) {
|
||||
JSInstance jsInstance, ReadableNativeArray jsArguments, int atIndex) {
|
||||
return DynamicFromArray.create(jsArguments, atIndex);
|
||||
}
|
||||
};
|
||||
@@ -102,7 +113,7 @@ public class JavaMethodWrapper implements NativeModule.NativeMethod {
|
||||
new ArgumentExtractor<ReadableMap>() {
|
||||
@Override
|
||||
public ReadableMap extractArgument(
|
||||
JSInstance jsInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) {
|
||||
JSInstance jsInstance, ReadableNativeArray jsArguments, int atIndex) {
|
||||
return jsArguments.getMap(atIndex);
|
||||
}
|
||||
};
|
||||
@@ -111,12 +122,12 @@ public class JavaMethodWrapper implements NativeModule.NativeMethod {
|
||||
new ArgumentExtractor<Callback>() {
|
||||
@Override
|
||||
public @Nullable Callback extractArgument(
|
||||
JSInstance jsInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) {
|
||||
JSInstance jsInstance, ReadableNativeArray jsArguments, int atIndex) {
|
||||
if (jsArguments.isNull(atIndex)) {
|
||||
return null;
|
||||
} else {
|
||||
int id = (int) jsArguments.getDouble(atIndex);
|
||||
return new com.facebook.react.bridge.CallbackImpl(jsInstance, executorToken, id);
|
||||
return new com.facebook.react.bridge.CallbackImpl(jsInstance, id);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -130,11 +141,11 @@ public class JavaMethodWrapper implements NativeModule.NativeMethod {
|
||||
|
||||
@Override
|
||||
public Promise extractArgument(
|
||||
JSInstance jsInstance, ExecutorToken executorToken, ReadableNativeArray jsArguments, int atIndex) {
|
||||
JSInstance jsInstance, ReadableNativeArray jsArguments, int atIndex) {
|
||||
Callback resolve = ARGUMENT_EXTRACTOR_CALLBACK
|
||||
.extractArgument(jsInstance, executorToken, jsArguments, atIndex);
|
||||
.extractArgument(jsInstance, jsArguments, atIndex);
|
||||
Callback reject = ARGUMENT_EXTRACTOR_CALLBACK
|
||||
.extractArgument(jsInstance, executorToken, jsArguments, atIndex + 1);
|
||||
.extractArgument(jsInstance, jsArguments, atIndex + 1);
|
||||
return new PromiseImpl(resolve, reject);
|
||||
}
|
||||
};
|
||||
@@ -144,9 +155,7 @@ public class JavaMethodWrapper implements NativeModule.NativeMethod {
|
||||
if (tryCommon != '\0') {
|
||||
return tryCommon;
|
||||
}
|
||||
if (paramClass == ExecutorToken.class) {
|
||||
return 'T';
|
||||
} else if (paramClass == Callback.class) {
|
||||
if (paramClass == Callback.class) {
|
||||
return 'X';
|
||||
} else if (paramClass == Promise.class) {
|
||||
return 'P';
|
||||
@@ -269,50 +278,20 @@ public class JavaMethodWrapper implements NativeModule.NativeMethod {
|
||||
|
||||
for (int i = 0; i < paramTypes.length; i++) {
|
||||
Class paramClass = paramTypes[i];
|
||||
if (paramClass == ExecutorToken.class) {
|
||||
if (!mModuleWrapper.supportsWebWorkers()) {
|
||||
throw new RuntimeException(
|
||||
"Module " + mModuleWrapper.getName() + " doesn't support web workers, but " +
|
||||
mMethod.getName() +
|
||||
" takes an ExecutorToken.");
|
||||
}
|
||||
} else if (paramClass == Promise.class) {
|
||||
if (paramClass == Promise.class) {
|
||||
Assertions.assertCondition(
|
||||
i == paramTypes.length - 1, "Promise must be used as last parameter only");
|
||||
}
|
||||
builder.append(paramTypeToChar(paramClass));
|
||||
}
|
||||
|
||||
// Modules that support web workers are expected to take an ExecutorToken as the first
|
||||
// parameter to all their @ReactMethod-annotated methods.
|
||||
if (mModuleWrapper.supportsWebWorkers()) {
|
||||
if (builder.charAt(2) != 'T') {
|
||||
throw new RuntimeException(
|
||||
"Module " + mModuleWrapper.getName() + " supports web workers, but " + mMethod.getName() +
|
||||
"does not take an ExecutorToken as its first parameter.");
|
||||
}
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private ArgumentExtractor[] buildArgumentExtractors(Class[] paramTypes) {
|
||||
// Modules that support web workers are expected to take an ExecutorToken as the first
|
||||
// parameter to all their @ReactMethod-annotated methods. We compensate for that here.
|
||||
int executorTokenOffset = 0;
|
||||
if (mModuleWrapper.supportsWebWorkers()) {
|
||||
if (paramTypes[0] != ExecutorToken.class) {
|
||||
throw new RuntimeException(
|
||||
"Module " + mModuleWrapper.getName() + " supports web workers, but " + mMethod.getName() +
|
||||
"does not take an ExecutorToken as its first parameter.");
|
||||
}
|
||||
executorTokenOffset = 1;
|
||||
}
|
||||
|
||||
ArgumentExtractor[] argumentExtractors = new ArgumentExtractor[paramTypes.length - executorTokenOffset];
|
||||
for (int i = 0; i < paramTypes.length - executorTokenOffset; i += argumentExtractors[i].getJSArgumentsNeeded()) {
|
||||
int paramIndex = i + executorTokenOffset;
|
||||
Class argumentClass = paramTypes[paramIndex];
|
||||
ArgumentExtractor[] argumentExtractors = new ArgumentExtractor[paramTypes.length];
|
||||
for (int i = 0; i < paramTypes.length; i += argumentExtractors[i].getJSArgumentsNeeded()) {
|
||||
Class argumentClass = paramTypes[i];
|
||||
if (argumentClass == Boolean.class || argumentClass == boolean.class) {
|
||||
argumentExtractors[i] = ARGUMENT_EXTRACTOR_BOOLEAN;
|
||||
} else if (argumentClass == Integer.class || argumentClass == int.class) {
|
||||
@@ -328,7 +307,7 @@ public class JavaMethodWrapper implements NativeModule.NativeMethod {
|
||||
} else if (argumentClass == Promise.class) {
|
||||
argumentExtractors[i] = ARGUMENT_EXTRACTOR_PROMISE;
|
||||
Assertions.assertCondition(
|
||||
paramIndex == paramTypes.length - 1, "Promise must be used as last parameter only");
|
||||
i == paramTypes.length - 1, "Promise must be used as last parameter only");
|
||||
} else if (argumentClass == ReadableMap.class) {
|
||||
argumentExtractors[i] = ARGUMENT_EXTRACTOR_MAP;
|
||||
} else if (argumentClass == ReadableArray.class) {
|
||||
@@ -357,7 +336,7 @@ public class JavaMethodWrapper implements NativeModule.NativeMethod {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(JSInstance jsInstance, ExecutorToken executorToken, ReadableNativeArray parameters) {
|
||||
public void invoke(JSInstance jsInstance, ReadableNativeArray parameters) {
|
||||
String traceName = mModuleWrapper.getName() + "." + mMethod.getName();
|
||||
SystraceMessage.beginSection(TRACE_TAG_REACT_JAVA_BRIDGE, "callJavaModuleMethod")
|
||||
.arg("method", traceName)
|
||||
@@ -374,18 +353,11 @@ public class JavaMethodWrapper implements NativeModule.NativeMethod {
|
||||
traceName + " got " + parameters.size() + " arguments, expected " + mJSArgumentsNeeded);
|
||||
}
|
||||
|
||||
// Modules that support web workers are expected to take an ExecutorToken as the first
|
||||
// parameter to all their @ReactMethod-annotated methods. We compensate for that here.
|
||||
int i = 0, jsArgumentsConsumed = 0;
|
||||
int executorTokenOffset = 0;
|
||||
if (mModuleWrapper.supportsWebWorkers()) {
|
||||
mArguments[0] = executorToken;
|
||||
executorTokenOffset = 1;
|
||||
}
|
||||
try {
|
||||
for (; i < mArgumentExtractors.length; i++) {
|
||||
mArguments[i + executorTokenOffset] = mArgumentExtractors[i].extractArgument(
|
||||
jsInstance, executorToken, parameters, jsArgumentsConsumed);
|
||||
mArguments[i] = mArgumentExtractors[i].extractArgument(
|
||||
jsInstance, parameters, jsArgumentsConsumed);
|
||||
jsArgumentsConsumed += mArgumentExtractors[i].getJSArgumentsNeeded();
|
||||
}
|
||||
} catch (UnexpectedNativeTypeException e) {
|
||||
|
||||
@@ -20,7 +20,6 @@ import java.util.Set;
|
||||
|
||||
import com.facebook.proguard.annotations.DoNotStrip;
|
||||
import com.facebook.react.bridge.BaseJavaModule;
|
||||
import com.facebook.react.bridge.ExecutorToken;
|
||||
import com.facebook.react.bridge.JSInstance;
|
||||
import com.facebook.react.bridge.NativeArray;
|
||||
import com.facebook.react.bridge.NativeModule;
|
||||
@@ -155,16 +154,11 @@ public class JavaModuleWrapper {
|
||||
}
|
||||
|
||||
@DoNotStrip
|
||||
public boolean supportsWebWorkers() {
|
||||
return mModuleHolder.getSupportsWebWorkers();
|
||||
}
|
||||
|
||||
@DoNotStrip
|
||||
public void invoke(ExecutorToken token, int methodId, ReadableNativeArray parameters) {
|
||||
public void invoke(int methodId, ReadableNativeArray parameters) {
|
||||
if (mMethods == null || methodId >= mMethods.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mMethods.get(methodId).invoke(mJSInstance, token, parameters);
|
||||
mMethods.get(methodId).invoke(mJSInstance, parameters);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,6 @@ public class ModuleHolder {
|
||||
|
||||
private final String mName;
|
||||
private final boolean mCanOverrideExistingModule;
|
||||
private final boolean mSupportsWebWorkers;
|
||||
private final boolean mHasConstants;
|
||||
|
||||
private @Nullable Provider<? extends NativeModule> mProvider;
|
||||
@@ -42,7 +41,6 @@ public class ModuleHolder {
|
||||
public ModuleHolder(ReactModuleInfo moduleInfo, Provider<? extends NativeModule> provider) {
|
||||
mName = moduleInfo.name();
|
||||
mCanOverrideExistingModule = moduleInfo.canOverrideExistingModule();
|
||||
mSupportsWebWorkers = moduleInfo.supportsWebWorkers();
|
||||
mHasConstants = moduleInfo.hasConstants();
|
||||
mProvider = provider;
|
||||
if (moduleInfo.needsEagerInit()) {
|
||||
@@ -53,7 +51,6 @@ public class ModuleHolder {
|
||||
public ModuleHolder(NativeModule nativeModule) {
|
||||
mName = nativeModule.getName();
|
||||
mCanOverrideExistingModule = nativeModule.canOverrideExistingModule();
|
||||
mSupportsWebWorkers = nativeModule.supportsWebWorkers();
|
||||
mHasConstants = true;
|
||||
mModule = nativeModule;
|
||||
}
|
||||
@@ -85,10 +82,6 @@ public class ModuleHolder {
|
||||
return mCanOverrideExistingModule;
|
||||
}
|
||||
|
||||
public boolean getSupportsWebWorkers() {
|
||||
return mSupportsWebWorkers;
|
||||
}
|
||||
|
||||
public boolean getHasConstants() {
|
||||
return mHasConstants;
|
||||
}
|
||||
|
||||
@@ -13,8 +13,6 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import com.facebook.react.bridge.BaseJavaModule;
|
||||
import com.facebook.react.bridge.ExecutorToken;
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
|
||||
import static java.lang.annotation.ElementType.TYPE;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
@@ -38,29 +36,6 @@ public @interface ReactModule {
|
||||
*/
|
||||
boolean canOverrideExistingModule() default false;
|
||||
|
||||
/**
|
||||
* In order to support web workers, a module must be aware that it can be invoked from multiple
|
||||
* different JS VMs. Supporting web workers means recognizing things like:
|
||||
*
|
||||
* 1) ids (e.g. timer ids, request ids, etc.) may only unique on a per-VM basis
|
||||
* 2) the module needs to make sure to enqueue callbacks and JS module calls to the correct VM
|
||||
*
|
||||
* In order to facilitate this, modules that support web workers will have all their @ReactMethod-
|
||||
* annotated methods passed a {@link ExecutorToken} as the first parameter before any arguments
|
||||
* from JS. This ExecutorToken internally maps to a specific JS VM and can be used by the
|
||||
* framework to route calls appropriately. In order to make JS module calls correctly, start using
|
||||
* the version of {@link ReactContext#getJSModule(ExecutorToken, Class)} that takes an
|
||||
* ExecutorToken. It will ensure that any calls you dispatch to the returned object will go to
|
||||
* the right VM. For Callbacks, you don't have to do anything special -- the framework
|
||||
* automatically tags them with the correct ExecutorToken when the are created.
|
||||
*
|
||||
* Note: even though calls can come from multiple JS VMs on multiple threads, calls to this module
|
||||
* will still only occur on a single thread.
|
||||
*
|
||||
* @return whether this module supports web workers.
|
||||
*/
|
||||
boolean supportsWebWorkers() default false;
|
||||
|
||||
/**
|
||||
* Whether this module needs to be loaded immediately.
|
||||
*/
|
||||
|
||||
@@ -10,19 +10,16 @@ public class ReactModuleInfo {
|
||||
|
||||
private final String mName;
|
||||
private final boolean mCanOverrideExistingModule;
|
||||
private final boolean mSupportsWebWorkers;
|
||||
private final boolean mNeedsEagerInit;
|
||||
private final boolean mHasConstants;
|
||||
|
||||
public ReactModuleInfo(
|
||||
String name,
|
||||
boolean canOverrideExistingModule,
|
||||
boolean supportsWebWorkers,
|
||||
boolean needsEagerInit,
|
||||
boolean hasConstants) {
|
||||
mName = name;
|
||||
mCanOverrideExistingModule = canOverrideExistingModule;
|
||||
mSupportsWebWorkers = supportsWebWorkers;
|
||||
mNeedsEagerInit = needsEagerInit;
|
||||
mHasConstants = hasConstants;
|
||||
}
|
||||
@@ -35,10 +32,6 @@ public class ReactModuleInfo {
|
||||
return mCanOverrideExistingModule;
|
||||
}
|
||||
|
||||
public boolean supportsWebWorkers() {
|
||||
return mSupportsWebWorkers;
|
||||
}
|
||||
|
||||
public boolean needsEagerInit() {
|
||||
return mNeedsEagerInit;
|
||||
}
|
||||
|
||||
@@ -175,7 +175,6 @@ public class ReactModuleSpecProcessor extends AbstractProcessor {
|
||||
.append("new ReactModuleInfo(")
|
||||
.append("\"").append(reactModule.name()).append("\"").append(", ")
|
||||
.append(reactModule.canOverrideExistingModule()).append(", ")
|
||||
.append(reactModule.supportsWebWorkers()).append(", ")
|
||||
.append(reactModule.needsEagerInit()).append(", ")
|
||||
.append(hasConstants)
|
||||
.append(")")
|
||||
|
||||
@@ -18,7 +18,6 @@ import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
import com.facebook.react.bridge.ReactMethod;
|
||||
import com.facebook.react.bridge.JavaScriptModule;
|
||||
import com.facebook.react.bridge.SupportsWebWorkers;
|
||||
import com.facebook.react.bridge.UiThreadUtil;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.module.annotations.ReactModule;
|
||||
@@ -29,7 +28,6 @@ import com.facebook.react.module.annotations.ReactModule;
|
||||
@ReactModule(name = "DeviceEventManager")
|
||||
public class DeviceEventManagerModule extends ReactContextBaseJavaModule {
|
||||
|
||||
@SupportsWebWorkers
|
||||
public interface RCTDeviceEventEmitter extends JavaScriptModule {
|
||||
void emit(String eventName, @Nullable Object data);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user