diff --git a/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp b/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp index 7d5b1acf483..659c8235a64 100644 --- a/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp +++ b/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp @@ -92,12 +92,6 @@ CatalystInstanceImpl::initHybrid(jni::alias_ref) { CatalystInstanceImpl::CatalystInstanceImpl() : instance_(std::make_unique()) {} -CatalystInstanceImpl::~CatalystInstanceImpl() { - if (moduleMessageQueue_ != NULL) { - moduleMessageQueue_->quitSynchronous(); - } -} - void CatalystInstanceImpl::registerNatives() { registerHybrid({ makeNativeMethod("initHybrid", CatalystInstanceImpl::initHybrid), diff --git a/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.h b/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.h index dd9990ef090..c40a691232c 100644 --- a/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.h +++ b/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.h @@ -37,7 +37,6 @@ class CatalystInstanceImpl : public jni::HybridClass { "Lcom/facebook/react/bridge/CatalystInstanceImpl;"; static jni::local_ref initHybrid(jni::alias_ref); - ~CatalystInstanceImpl() override; static void registerNatives(); diff --git a/ReactCommon/turbomodule/core/platform/android/JavaTurboModule.cpp b/ReactCommon/turbomodule/core/platform/android/JavaTurboModule.cpp index 4b5d8d6e953..82fbc928fb6 100644 --- a/ReactCommon/turbomodule/core/platform/android/JavaTurboModule.cpp +++ b/ReactCommon/turbomodule/core/platform/android/JavaTurboModule.cpp @@ -31,6 +31,26 @@ JavaTurboModule::JavaTurboModule(const InitParams ¶ms) instance_(jni::make_global(params.instance)), nativeInvoker_(params.nativeInvoker) {} +JavaTurboModule::~JavaTurboModule() { + /** + * TODO(T75896241): In E2E tests, instance_ is null. Investigate why. Can we + * get rid of this null check? + */ + if (!instance_) { + return; + } + + nativeInvoker_->invokeAsync([instance = std::move(instance_)]() mutable { + /** + * Reset the global NativeModule ref on the NativeModules thread. Why: + * - ~JavaTurboModule() can be called on a non-JVM thread. If we reset the + * global ref in ~JavaTurboModule(), we might access the JVM from a + * non-JVM thread, which will crash the app. + */ + instance.reset(); + }); +} + bool JavaTurboModule::isPromiseAsyncDispatchEnabled_ = false; void JavaTurboModule::enablePromiseAsyncDispatch(bool enable) { isPromiseAsyncDispatchEnabled_ = enable; diff --git a/ReactCommon/turbomodule/core/platform/android/JavaTurboModule.h b/ReactCommon/turbomodule/core/platform/android/JavaTurboModule.h index 642cacb194a..93acda48fcf 100644 --- a/ReactCommon/turbomodule/core/platform/android/JavaTurboModule.h +++ b/ReactCommon/turbomodule/core/platform/android/JavaTurboModule.h @@ -41,6 +41,7 @@ class JSI_EXPORT JavaTurboModule : public TurboModule { }; JavaTurboModule(const InitParams ¶ms); + virtual ~JavaTurboModule(); jsi::Value invokeJavaMethod( jsi::Runtime &runtime, TurboModuleMethodValueKind valueKind,