diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/BridgelessReactContext.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/BridgelessReactContext.java index 742775ea32bda8..5fa3947959105c 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/BridgelessReactContext.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/BridgelessReactContext.java @@ -12,6 +12,7 @@ import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.Callback; import com.facebook.react.bridge.CatalystInstance; +import com.facebook.react.bridge.JavaScriptContextHolder; import com.facebook.react.bridge.JavaScriptModule; import com.facebook.react.bridge.JavaScriptModuleRegistry; import com.facebook.react.bridge.NativeArray; @@ -163,6 +164,13 @@ public Collection getNativeModules() { return mReactHost.getRuntimeExecutor(); } + @Override + @FrameworkAPI + @UnstableReactNativeAPI + public @Nullable JavaScriptContextHolder getJavaScriptContextHolder() { + return mReactHost.getJavaScriptContextHolder(); + } + @Override public void handleException(Exception e) { mReactHost.handleHostException(e); diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.java index 08dca74feed53e..674aeb42f9f7fd 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.java @@ -29,6 +29,7 @@ import com.facebook.react.ReactInstanceEventListener; import com.facebook.react.bridge.Callback; import com.facebook.react.bridge.JSBundleLoader; +import com.facebook.react.bridge.JavaScriptContextHolder; import com.facebook.react.bridge.MemoryPressureListener; import com.facebook.react.bridge.NativeArray; import com.facebook.react.bridge.NativeModule; @@ -599,6 +600,15 @@ RuntimeExecutor getRuntimeExecutor() { return null; } + @Nullable + JavaScriptContextHolder getJavaScriptContextHolder() { + final ReactInstance reactInstance = mReactInstanceTaskRef.get().getResult(); + if (reactInstance != null) { + return reactInstance.getJavaScriptContextHolder(); + } + return null; + } + /* package */ DefaultHardwareBackBtnHandler getDefaultBackButtonHandler() { return () -> { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactInstance.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactInstance.java index d0d42462bf80f6..b0d7eee6950213 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactInstance.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactInstance.java @@ -20,6 +20,7 @@ import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.JSBundleLoader; import com.facebook.react.bridge.JSBundleLoaderDelegate; +import com.facebook.react.bridge.JavaScriptContextHolder; import com.facebook.react.bridge.LifecycleEventListener; import com.facebook.react.bridge.NativeArray; import com.facebook.react.bridge.NativeMap; @@ -95,6 +96,8 @@ final class ReactInstance { private final JavaTimerManager mJavaTimerManager; private final BridgelessViewManagerResolver mViewManagerResolver; + private JavaScriptContextHolder mJavaScriptContextHolder; + @DoNotStrip @Nullable private ComponentNameResolverManager mComponentNameResolverManager; @DoNotStrip @Nullable private UIConstantsProviderManager mUIConstantsProviderManager; @@ -181,6 +184,8 @@ public void onHostDestroy() { bindingsInstaller, isProfiling); + mJavaScriptContextHolder = new JavaScriptContextHolder(getJavaScriptContext()); + // Set up TurboModules Systrace.beginSection( Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "ReactInstance.initialize#initTurboModules"); @@ -430,6 +435,10 @@ public Collection getNativeModules() { mFabricUIManager.stopSurface(surface.getSurfaceHandler()); } + public JavaScriptContextHolder getJavaScriptContextHolder() { + return mJavaScriptContextHolder; + } + /* --- Lifecycle methods --- */ @ThreadConfined("ReactHost") /* package */ void destroy() { @@ -440,6 +449,7 @@ public Collection getNativeModules() { mHybridData.resetNative(); mComponentNameResolverManager = null; mUIConstantsProviderManager = null; + mJavaScriptContextHolder.clear(); } /* --- Native methods --- */ @@ -475,6 +485,8 @@ private native HybridData initHybrid( private native RuntimeScheduler getRuntimeScheduler(); + private native long getJavaScriptContext(); + /* package */ native void callFunctionOnModule( String moduleName, String methodName, NativeArray args); diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JReactInstance.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JReactInstance.cpp index 0adccf64d7f1c1..ce3bc7b613e00d 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JReactInstance.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JReactInstance.cpp @@ -201,6 +201,10 @@ void JReactInstance::handleMemoryPressureJs(jint level) { instance_->handleMemoryPressureJs(level); } +jlong JReactInstance::getJavaScriptContext() { + return (jlong)(intptr_t)instance_->getJavaScriptContext(); +} + void JReactInstance::registerNatives() { registerHybrid({ makeNativeMethod("initHybrid", JReactInstance::initHybrid), @@ -230,6 +234,8 @@ void JReactInstance::registerNatives() { "registerSegmentNative", JReactInstance::registerSegment), makeNativeMethod( "handleMemoryPressureJs", JReactInstance::handleMemoryPressureJs), + makeNativeMethod( + "getJavaScriptContext", JReactInstance::getJavaScriptContext), }); } diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JReactInstance.h b/packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JReactInstance.h index b07ed7377fdfeb..6a28ea50c737e1 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JReactInstance.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JReactInstance.h @@ -105,6 +105,8 @@ class JReactInstance : public jni::HybridClass { nativeMethodCallInvokerHolder_; jni::global_ref jReactExceptionManager_; jni::global_ref jBindingsInstaller_; + + jlong getJavaScriptContext(); }; } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/runtime/ReactInstance.cpp b/packages/react-native/ReactCommon/react/runtime/ReactInstance.cpp index 0f5fca84bab8dc..b5ac263fedeb0a 100644 --- a/packages/react-native/ReactCommon/react/runtime/ReactInstance.cpp +++ b/packages/react-native/ReactCommon/react/runtime/ReactInstance.cpp @@ -463,4 +463,8 @@ void ReactInstance::handleMemoryPressureJs(int pressureLevel) { } } +void* ReactInstance::getJavaScriptContext() { + return &runtime_->getRuntime(); +} + } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/runtime/ReactInstance.h b/packages/react-native/ReactCommon/react/runtime/ReactInstance.h index 50a4f17a1ed724..c82656c77679b9 100644 --- a/packages/react-native/ReactCommon/react/runtime/ReactInstance.h +++ b/packages/react-native/ReactCommon/react/runtime/ReactInstance.h @@ -71,6 +71,8 @@ class ReactInstance final : private jsinspector_modern::InstanceTargetDelegate { */ void unregisterFromInspector(); + void* getJavaScriptContext(); + private: std::shared_ptr runtime_; std::shared_ptr jsMessageQueueThread_;