From 64dc8faa7b38ef4fb7e71416341d5014fa18b19e Mon Sep 17 00:00:00 2001 From: Mike Hardy Date: Fri, 18 Oct 2024 15:34:33 -0500 Subject: [PATCH] fix(android): forward-port getReactContext to new arch bridgeless mode ...but do so in a way that is backwards-compatible as the symbols required - do not show up at all until react-native 0.73 - moved to different package names in 0.74 --- .../invertase/notifee/NotifeeReactUtils.java | 43 ++++++++++++++++--- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/packages/react-native/android/src/main/java/io/invertase/notifee/NotifeeReactUtils.java b/packages/react-native/android/src/main/java/io/invertase/notifee/NotifeeReactUtils.java index 4c3b169b..2e2faa4c 100644 --- a/packages/react-native/android/src/main/java/io/invertase/notifee/NotifeeReactUtils.java +++ b/packages/react-native/android/src/main/java/io/invertase/notifee/NotifeeReactUtils.java @@ -12,6 +12,7 @@ import android.os.Looper; import android.util.Log; import android.util.SparseArray; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.lifecycle.Lifecycle; import androidx.lifecycle.ProcessLifecycleOwner; @@ -105,11 +106,43 @@ static void promiseResolver(Promise promise, Exception e) { } } + @SuppressLint("VisibleForTests") private static @Nullable ReactContext getReactContext() { - ReactNativeHost reactNativeHost = - ((ReactApplication) EventSubscriber.getContext()).getReactNativeHost(); - ReactInstanceManager reactInstanceManager = reactNativeHost.getReactInstanceManager(); - return reactInstanceManager.getCurrentReactContext(); + try { + + // Carefully try to load new architecture classes so we preserve backwards compatibility + // These symbols are only available in react-native >= 0.73 + try { + Class entryPoint = + Class.forName("com.facebook.react.defaults.DefaultNewArchitectureEntryPoint"); + Method bridgelessEnabled = entryPoint.getMethod("getBridgelessEnabled"); + Object result = bridgelessEnabled.invoke(null); + if (result == Boolean.TRUE) { + Log.d("getReactContext", "We are in bridgeless new architecture mode"); + Object reactApplication = EventSubscriber.getContext(); + Method getReactHost = reactApplication.getClass().getMethod("getReactHost"); + Object reactHostInstance = getReactHost.invoke(reactApplication); + Method getCurrentReactContext = + reactHostInstance.getClass().getMethod("getCurrentReactContext"); + return (ReactContext) getCurrentReactContext.invoke(reactHostInstance); + } else { + Log.d("getReactContext", "we are NOT in bridgeless new architecture mode"); + } + } catch (Exception e) { + Log.d("getReactContext", "New Architecture class load failed. Using fallback."); + } + + Log.d("getReactContext", "Determining ReactContext using fallback method"); + ReactNativeHost reactNativeHost = + ((ReactApplication) EventSubscriber.getContext()).getReactNativeHost(); + ReactInstanceManager reactInstanceManager = reactNativeHost.getReactInstanceManager(); + return reactInstanceManager.getCurrentReactContext(); + } catch (Exception e) { + Log.w("getReactContext", "ReactHost unexpectedly null", e); + } + + Log.w("getReactContext", "Unable to determine ReactContext"); + return null; } private static void initializeReactContext(GenericCallback callback) { @@ -121,7 +154,7 @@ private static void initializeReactContext(GenericCallback callback) { reactInstanceManager.addReactInstanceEventListener( new ReactInstanceManager.ReactInstanceEventListener() { @Override - public void onReactContextInitialized(final ReactContext reactContext) { + public void onReactContextInitialized(@NonNull final ReactContext reactContext) { reactInstanceManager.removeReactInstanceEventListener(this); new Handler(Looper.getMainLooper()).postDelayed(callback::call, 100); }