WebWorkers: Allow native modules to be notified when executors are unregistered
Summary: This will allow them to clean up resources when a web worker goes away. Reviewed By: mhorowitz, lexs Differential Revision: D2994721 fb-gh-sync-id: c7ca1afc7290e85038cf692a139f6478dba0ef61 shipit-source-id: c7ca1afc7290e85038cf692a139f6478dba0ef61
This commit is contained in:
parent
1bab7c5182
commit
6d5f9ddfff
|
@ -222,8 +222,10 @@ public class CatalystInstanceImpl implements CatalystInstance {
|
||||||
Systrace.unregisterListener(mTraceListener);
|
Systrace.unregisterListener(mTraceListener);
|
||||||
|
|
||||||
synchronouslyDisposeBridgeOnJSThread();
|
synchronouslyDisposeBridgeOnJSThread();
|
||||||
mReactQueueConfiguration.destroy();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mReactQueueConfiguration.destroy();
|
||||||
|
|
||||||
boolean wasIdle = (mPendingJSCalls.getAndSet(0) == 0);
|
boolean wasIdle = (mPendingJSCalls.getAndSet(0) == 0);
|
||||||
if (!wasIdle && !mBridgeIdleListeners.isEmpty()) {
|
if (!wasIdle && !mBridgeIdleListeners.isEmpty()) {
|
||||||
for (NotThreadSafeBridgeIdleDebugListener listener : mBridgeIdleListeners) {
|
for (NotThreadSafeBridgeIdleDebugListener listener : mBridgeIdleListeners) {
|
||||||
|
@ -293,12 +295,12 @@ public class CatalystInstanceImpl implements CatalystInstance {
|
||||||
@Override
|
@Override
|
||||||
public void handleMemoryPressure(final MemoryPressure level) {
|
public void handleMemoryPressure(final MemoryPressure level) {
|
||||||
mReactQueueConfiguration.getJSQueueThread().runOnQueue(
|
mReactQueueConfiguration.getJSQueueThread().runOnQueue(
|
||||||
new Runnable() {
|
new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
Assertions.assertNotNull(mBridge).handleMemoryPressure(level);
|
Assertions.assertNotNull(mBridge).handleMemoryPressure(level);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -399,12 +401,14 @@ public class CatalystInstanceImpl implements CatalystInstance {
|
||||||
public void call(ExecutorToken executorToken, int moduleId, int methodId, ReadableNativeArray parameters) {
|
public void call(ExecutorToken executorToken, int moduleId, int methodId, ReadableNativeArray parameters) {
|
||||||
mReactQueueConfiguration.getNativeModulesQueueThread().assertIsOnThread();
|
mReactQueueConfiguration.getNativeModulesQueueThread().assertIsOnThread();
|
||||||
|
|
||||||
// Suppress any callbacks if destroyed - will only lead to sadness.
|
synchronized (mTeardownLock) {
|
||||||
if (mDestroyed) {
|
// Suppress any callbacks if destroyed - will only lead to sadness.
|
||||||
return;
|
if (mDestroyed) {
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
mJavaRegistry.call(CatalystInstanceImpl.this, executorToken, moduleId, methodId, parameters);
|
mJavaRegistry.call(CatalystInstanceImpl.this, executorToken, moduleId, methodId, parameters);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -415,17 +419,38 @@ public class CatalystInstanceImpl implements CatalystInstance {
|
||||||
// native modules could be in a bad state so we don't want to call anything on them. We
|
// native modules could be in a bad state so we don't want to call anything on them. We
|
||||||
// still want to trigger the debug listener since it allows instrumentation tests to end and
|
// still want to trigger the debug listener since it allows instrumentation tests to end and
|
||||||
// check their assertions without waiting for a timeout.
|
// check their assertions without waiting for a timeout.
|
||||||
if (!mDestroyed) {
|
synchronized (mTeardownLock) {
|
||||||
Systrace.beginSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "onBatchComplete");
|
if (!mDestroyed) {
|
||||||
try {
|
Systrace.beginSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "onBatchComplete");
|
||||||
mJavaRegistry.onBatchComplete();
|
try {
|
||||||
} finally {
|
mJavaRegistry.onBatchComplete();
|
||||||
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
|
} finally {
|
||||||
|
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
decrementPendingJSCalls();
|
decrementPendingJSCalls();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onExecutorUnregistered(ExecutorToken executorToken) {
|
||||||
|
mReactQueueConfiguration.getNativeModulesQueueThread().assertIsOnThread();
|
||||||
|
|
||||||
|
// Since onCatalystInstanceDestroy happens on the UI thread, we don't want to also execute
|
||||||
|
// this callback on the native modules thread at the same time. Longer term, onCatalystInstanceDestroy
|
||||||
|
// should probably be executed on the native modules thread as well instead.
|
||||||
|
synchronized (mTeardownLock) {
|
||||||
|
if (!mDestroyed) {
|
||||||
|
Systrace.beginSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "onExecutorUnregistered");
|
||||||
|
try {
|
||||||
|
mJavaRegistry.onExecutorUnregistered(executorToken);
|
||||||
|
} finally {
|
||||||
|
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class NativeExceptionHandler implements QueueThreadExceptionHandler {
|
private class NativeExceptionHandler implements QueueThreadExceptionHandler {
|
||||||
|
|
|
@ -30,6 +30,7 @@ public class NativeModuleRegistry {
|
||||||
private final List<ModuleDefinition> mModuleTable;
|
private final List<ModuleDefinition> mModuleTable;
|
||||||
private final Map<Class<? extends NativeModule>, NativeModule> mModuleInstances;
|
private final Map<Class<? extends NativeModule>, NativeModule> mModuleInstances;
|
||||||
private final ArrayList<OnBatchCompleteListener> mBatchCompleteListenerModules;
|
private final ArrayList<OnBatchCompleteListener> mBatchCompleteListenerModules;
|
||||||
|
private final ArrayList<OnExecutorUnregisteredListener> mOnExecutorUnregisteredListenerModules;
|
||||||
|
|
||||||
private NativeModuleRegistry(
|
private NativeModuleRegistry(
|
||||||
List<ModuleDefinition> moduleTable,
|
List<ModuleDefinition> moduleTable,
|
||||||
|
@ -37,12 +38,16 @@ public class NativeModuleRegistry {
|
||||||
mModuleTable = moduleTable;
|
mModuleTable = moduleTable;
|
||||||
mModuleInstances = moduleInstances;
|
mModuleInstances = moduleInstances;
|
||||||
|
|
||||||
mBatchCompleteListenerModules = new ArrayList<OnBatchCompleteListener>(mModuleTable.size());
|
mBatchCompleteListenerModules = new ArrayList<>(mModuleTable.size());
|
||||||
|
mOnExecutorUnregisteredListenerModules = new ArrayList<>(mModuleTable.size());
|
||||||
for (int i = 0; i < mModuleTable.size(); i++) {
|
for (int i = 0; i < mModuleTable.size(); i++) {
|
||||||
ModuleDefinition definition = mModuleTable.get(i);
|
ModuleDefinition definition = mModuleTable.get(i);
|
||||||
if (definition.target instanceof OnBatchCompleteListener) {
|
if (definition.target instanceof OnBatchCompleteListener) {
|
||||||
mBatchCompleteListenerModules.add((OnBatchCompleteListener) definition.target);
|
mBatchCompleteListenerModules.add((OnBatchCompleteListener) definition.target);
|
||||||
}
|
}
|
||||||
|
if (definition.target instanceof OnExecutorUnregisteredListener) {
|
||||||
|
mOnExecutorUnregisteredListenerModules.add((OnExecutorUnregisteredListener) definition.target);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,6 +140,12 @@ public class NativeModuleRegistry {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void onExecutorUnregistered(ExecutorToken executorToken) {
|
||||||
|
for (int i = 0; i < mOnExecutorUnregisteredListenerModules.size(); i++) {
|
||||||
|
mOnExecutorUnregisteredListenerModules.get(i).onExecutorDestroyed(executorToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public <T extends NativeModule> T getModule(Class<T> moduleInterface) {
|
public <T extends NativeModule> T getModule(Class<T> moduleInterface) {
|
||||||
return (T) Assertions.assertNotNull(mModuleInstances.get(moduleInterface));
|
return (T) Assertions.assertNotNull(mModuleInstances.get(moduleInterface));
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
}
|
|
@ -19,4 +19,7 @@ public interface ReactCallback {
|
||||||
|
|
||||||
@DoNotStrip
|
@DoNotStrip
|
||||||
void onBatchComplete();
|
void onBatchComplete();
|
||||||
|
|
||||||
|
@DoNotStrip
|
||||||
|
void onExecutorUnregistered(ExecutorToken executorToken);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ namespace react {
|
||||||
Bridge::Bridge(
|
Bridge::Bridge(
|
||||||
JSExecutorFactory* jsExecutorFactory,
|
JSExecutorFactory* jsExecutorFactory,
|
||||||
std::unique_ptr<ExecutorTokenFactory> executorTokenFactory,
|
std::unique_ptr<ExecutorTokenFactory> executorTokenFactory,
|
||||||
Callback callback) :
|
std::unique_ptr<BridgeCallback> callback) :
|
||||||
m_callback(std::move(callback)),
|
m_callback(std::move(callback)),
|
||||||
m_destroyed(std::make_shared<bool>(false)),
|
m_destroyed(std::make_shared<bool>(false)),
|
||||||
m_executorTokenFactory(std::move(executorTokenFactory)) {
|
m_executorTokenFactory(std::move(executorTokenFactory)) {
|
||||||
|
@ -174,7 +174,7 @@ void Bridge::callNativeModules(JSExecutor& executor, const std::string& callJSON
|
||||||
if (*m_destroyed) {
|
if (*m_destroyed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_callback(getTokenForExecutor(executor), parseMethodCalls(callJSON), isEndOfBatch);
|
m_callback->onCallNativeModules(getTokenForExecutor(executor), parseMethodCalls(callJSON), isEndOfBatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
ExecutorToken Bridge::getMainExecutorToken() const {
|
ExecutorToken Bridge::getMainExecutorToken() const {
|
||||||
|
@ -214,7 +214,7 @@ std::unique_ptr<JSExecutor> Bridge::unregisterExecutor(ExecutorToken executorTok
|
||||||
m_executorTokenMap.erase(executor.get());
|
m_executorTokenMap.erase(executor.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Notify native modules that ExecutorToken destroyed
|
m_callback->onExecutorUnregistered(executorToken);
|
||||||
|
|
||||||
return executor;
|
return executor;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,18 @@ struct dynamic;
|
||||||
namespace facebook {
|
namespace facebook {
|
||||||
namespace react {
|
namespace react {
|
||||||
|
|
||||||
|
class BridgeCallback {
|
||||||
|
public:
|
||||||
|
virtual ~BridgeCallback() {};
|
||||||
|
|
||||||
|
virtual void onCallNativeModules(
|
||||||
|
ExecutorToken executorToken,
|
||||||
|
std::vector<MethodCall>&& calls,
|
||||||
|
bool isEndOfBatch) = 0;
|
||||||
|
|
||||||
|
virtual void onExecutorUnregistered(ExecutorToken executorToken) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
class Bridge;
|
class Bridge;
|
||||||
class ExecutorRegistration {
|
class ExecutorRegistration {
|
||||||
public:
|
public:
|
||||||
|
@ -39,15 +51,13 @@ public:
|
||||||
|
|
||||||
class Bridge {
|
class Bridge {
|
||||||
public:
|
public:
|
||||||
typedef std::function<void(ExecutorToken executorToken, std::vector<MethodCall>, bool isEndOfBatch)> Callback;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This must be called on the main JS thread.
|
* This must be called on the main JS thread.
|
||||||
*/
|
*/
|
||||||
Bridge(
|
Bridge(
|
||||||
JSExecutorFactory* jsExecutorFactory,
|
JSExecutorFactory* jsExecutorFactory,
|
||||||
std::unique_ptr<ExecutorTokenFactory> executorTokenFactory,
|
std::unique_ptr<ExecutorTokenFactory> executorTokenFactory,
|
||||||
Callback callback);
|
std::unique_ptr<BridgeCallback> callback);
|
||||||
virtual ~Bridge();
|
virtual ~Bridge();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -128,7 +138,7 @@ public:
|
||||||
*/
|
*/
|
||||||
void destroy();
|
void destroy();
|
||||||
private:
|
private:
|
||||||
Callback m_callback;
|
std::unique_ptr<BridgeCallback> m_callback;
|
||||||
// This is used to avoid a race condition where a proxyCallback gets queued after ~Bridge(),
|
// This is used to avoid a race condition where a proxyCallback gets queued after ~Bridge(),
|
||||||
// on the same thread. In that case, the callback will try to run the task on m_callback which
|
// on the same thread. In that case, the callback will try to run the task on m_callback which
|
||||||
// will have been destroyed within ~Bridge(), thus causing a SIGSEGV.
|
// will have been destroyed within ~Bridge(), thus causing a SIGSEGV.
|
||||||
|
|
|
@ -567,6 +567,7 @@ namespace bridge {
|
||||||
|
|
||||||
static jmethodID gCallbackMethod;
|
static jmethodID gCallbackMethod;
|
||||||
static jmethodID gOnBatchCompleteMethod;
|
static jmethodID gOnBatchCompleteMethod;
|
||||||
|
static jmethodID gOnExecutorUnregisteredMethod;
|
||||||
static jmethodID gLogMarkerMethod;
|
static jmethodID gLogMarkerMethod;
|
||||||
|
|
||||||
struct CountableBridge : Bridge, Countable {
|
struct CountableBridge : Bridge, Countable {
|
||||||
|
@ -582,7 +583,7 @@ static void logMarker(const std::string& marker) {
|
||||||
env->DeleteLocalRef(jmarker);
|
env->DeleteLocalRef(jmarker);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void makeJavaCall(JNIEnv* env, ExecutorToken executorToken, jobject callback, MethodCall&& call) {
|
static void makeJavaCall(JNIEnv* env, ExecutorToken executorToken, jobject callback, const MethodCall& call) {
|
||||||
if (call.arguments.isNull()) {
|
if (call.arguments.isNull()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -607,33 +608,51 @@ static void signalBatchComplete(JNIEnv* env, jobject callback) {
|
||||||
env->CallVoidMethod(callback, gOnBatchCompleteMethod);
|
env->CallVoidMethod(callback, gOnBatchCompleteMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dispatchCallbacksToJava(ExecutorToken executorToken,
|
class PlatformBridgeCallback : public BridgeCallback {
|
||||||
const RefPtr<WeakReference>& weakCallback,
|
public:
|
||||||
const RefPtr<WeakReference>& weakCallbackQueueThread,
|
PlatformBridgeCallback(
|
||||||
std::vector<MethodCall>&& calls,
|
RefPtr<WeakReference> weakCallback_,
|
||||||
bool isEndOfBatch) {
|
RefPtr<WeakReference> weakCallbackQueueThread_) :
|
||||||
auto env = Environment::current();
|
weakCallback_(std::move(weakCallback_)),
|
||||||
if (env->ExceptionCheck()) {
|
weakCallbackQueueThread_(std::move(weakCallbackQueueThread_)) {}
|
||||||
FBLOGW("Dropped calls because of pending exception");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ResolvedWeakReference callbackQueueThread(weakCallbackQueueThread);
|
void executeCallbackOnCallbackQueueThread(std::function<void(ResolvedWeakReference&)>&& runnable) {
|
||||||
if (!callbackQueueThread) {
|
|
||||||
FBLOGW("Dropped calls because of callback queue thread went away");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto runnableFunction = std::bind([executorToken, weakCallback, isEndOfBatch] (std::vector<MethodCall>& calls) {
|
|
||||||
auto env = Environment::current();
|
auto env = Environment::current();
|
||||||
if (env->ExceptionCheck()) {
|
if (env->ExceptionCheck()) {
|
||||||
FBLOGW("Dropped calls because of pending exception");
|
FBLOGW("Dropped callback because of pending exception");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ResolvedWeakReference callback(weakCallback);
|
|
||||||
if (callback) {
|
ResolvedWeakReference callbackQueueThread(weakCallbackQueueThread_);
|
||||||
for (auto&& call : calls) {
|
if (!callbackQueueThread) {
|
||||||
makeJavaCall(env, executorToken, callback, std::move(call));
|
FBLOGW("Dropped callback because callback queue thread went away");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto runnableWrapper = std::bind([this] (std::function<void(ResolvedWeakReference&)>& runnable) {
|
||||||
|
auto env = Environment::current();
|
||||||
|
if (env->ExceptionCheck()) {
|
||||||
|
FBLOGW("Dropped calls because of pending exception");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ResolvedWeakReference callback(weakCallback_);
|
||||||
|
if (callback) {
|
||||||
|
runnable(callback);
|
||||||
|
}
|
||||||
|
}, std::move(runnable));
|
||||||
|
|
||||||
|
auto jNativeRunnable = runnable::createNativeRunnable(env, std::move(runnableWrapper));
|
||||||
|
queue::enqueueNativeRunnableOnQueue(env, callbackQueueThread, jNativeRunnable.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void onCallNativeModules(
|
||||||
|
ExecutorToken executorToken,
|
||||||
|
std::vector<MethodCall>&& calls,
|
||||||
|
bool isEndOfBatch) override {
|
||||||
|
executeCallbackOnCallbackQueueThread([executorToken, calls, isEndOfBatch] (ResolvedWeakReference& callback) {
|
||||||
|
JNIEnv* env = Environment::current();
|
||||||
|
for (auto& call : calls) {
|
||||||
|
makeJavaCall(env, executorToken, callback, call);
|
||||||
if (env->ExceptionCheck()) {
|
if (env->ExceptionCheck()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -641,23 +660,31 @@ static void dispatchCallbacksToJava(ExecutorToken executorToken,
|
||||||
if (isEndOfBatch) {
|
if (isEndOfBatch) {
|
||||||
signalBatchComplete(env, callback);
|
signalBatchComplete(env, callback);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}, std::move(calls));
|
}
|
||||||
|
|
||||||
auto jNativeRunnable = runnable::createNativeRunnable(env, std::move(runnableFunction));
|
virtual void onExecutorUnregistered(ExecutorToken executorToken) override {
|
||||||
queue::enqueueNativeRunnableOnQueue(env, callbackQueueThread, jNativeRunnable.get());
|
executeCallbackOnCallbackQueueThread([executorToken] (ResolvedWeakReference& callback) {
|
||||||
}
|
JNIEnv *env = Environment::current();
|
||||||
|
env->CallVoidMethod(
|
||||||
|
callback,
|
||||||
|
gOnExecutorUnregisteredMethod,
|
||||||
|
static_cast<JExecutorTokenHolder*>(executorToken.getPlatformExecutorToken().get())->getJobj());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
RefPtr<WeakReference> weakCallback_;
|
||||||
|
RefPtr<WeakReference> weakCallbackQueueThread_;
|
||||||
|
};
|
||||||
|
|
||||||
static void create(JNIEnv* env, jobject obj, jobject executor, jobject callback,
|
static void create(JNIEnv* env, jobject obj, jobject executor, jobject callback,
|
||||||
jobject callbackQueueThread) {
|
jobject callbackQueueThread) {
|
||||||
auto weakCallback = createNew<WeakReference>(callback);
|
auto weakCallback = createNew<WeakReference>(callback);
|
||||||
auto weakCallbackQueueThread = createNew<WeakReference>(callbackQueueThread);
|
auto weakCallbackQueueThread = createNew<WeakReference>(callbackQueueThread);
|
||||||
auto bridgeCallback = [weakCallback, weakCallbackQueueThread] (ExecutorToken executorToken, std::vector<MethodCall> calls, bool isEndOfBatch) {
|
auto bridgeCallback = folly::make_unique<PlatformBridgeCallback>(weakCallback, weakCallbackQueueThread);
|
||||||
dispatchCallbacksToJava(executorToken, weakCallback, weakCallbackQueueThread, std::move(calls), isEndOfBatch);
|
|
||||||
};
|
|
||||||
auto nativeExecutorFactory = extractRefPtr<CountableJSExecutorFactory>(env, executor);
|
auto nativeExecutorFactory = extractRefPtr<CountableJSExecutorFactory>(env, executor);
|
||||||
auto executorTokenFactory = folly::make_unique<JExecutorTokenFactory>();
|
auto executorTokenFactory = folly::make_unique<JExecutorTokenFactory>();
|
||||||
auto bridge = createNew<CountableBridge>(nativeExecutorFactory.get(), std::move(executorTokenFactory), bridgeCallback);
|
auto bridge = createNew<CountableBridge>(nativeExecutorFactory.get(), std::move(executorTokenFactory), std::move(bridgeCallback));
|
||||||
setCountableForJava(env, obj, std::move(bridge));
|
setCountableForJava(env, obj, std::move(bridge));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -968,6 +995,7 @@ extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
|
||||||
jclass callbackClass = env->FindClass("com/facebook/react/bridge/ReactCallback");
|
jclass callbackClass = env->FindClass("com/facebook/react/bridge/ReactCallback");
|
||||||
bridge::gCallbackMethod = env->GetMethodID(callbackClass, "call", "(Lcom/facebook/react/bridge/ExecutorToken;IILcom/facebook/react/bridge/ReadableNativeArray;)V");
|
bridge::gCallbackMethod = env->GetMethodID(callbackClass, "call", "(Lcom/facebook/react/bridge/ExecutorToken;IILcom/facebook/react/bridge/ReadableNativeArray;)V");
|
||||||
bridge::gOnBatchCompleteMethod = env->GetMethodID(callbackClass, "onBatchComplete", "()V");
|
bridge::gOnBatchCompleteMethod = env->GetMethodID(callbackClass, "onBatchComplete", "()V");
|
||||||
|
bridge::gOnExecutorUnregisteredMethod = env->GetMethodID(callbackClass, "onExecutorUnregistered", "(Lcom/facebook/react/bridge/ExecutorToken;)V");
|
||||||
|
|
||||||
jclass markerClass = env->FindClass("com/facebook/react/bridge/ReactMarker");
|
jclass markerClass = env->FindClass("com/facebook/react/bridge/ReactMarker");
|
||||||
bridge::gLogMarkerMethod = env->GetStaticMethodID(markerClass, "logMarker", "(Ljava/lang/String;)V");
|
bridge::gLogMarkerMethod = env->GetStaticMethodID(markerClass, "logMarker", "(Ljava/lang/String;)V");
|
||||||
|
|
Loading…
Reference in New Issue