From 7176d11ce468ca37e9cbe8afcc1f6344c250dd0c Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Fri, 27 Sep 2024 01:49:38 -0700 Subject: [PATCH] ReactFragment should properly instantiate ReactDelegate on Bridgeless (#46623) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/46623 I've just noticed that ReactFragment is not properly instantiating the `ReactDelegate` with a ReactHost when on Bridgeless. This causes Fragments to crash when the app is on bridgeless mode. Fixes https://github.com/facebook/react-native/issues/46566 Changelog: [Android] [Fixed] - ReactFragment should properly instantiate ReactDelegate on Bridgeless Reviewed By: mdvacca Differential Revision: D63319977 fbshipit-source-id: 08256e35b2769e18df2d24f870ec5d98e5574f85 --- .../ReactAndroid/api/ReactAndroid.api | 1 + .../com/facebook/react/ReactFragment.java | 40 +++++++++++++++++-- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index e1909ad0345..ec0187c019c 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -192,6 +192,7 @@ public class com/facebook/react/ReactFragment : androidx/fragment/app/Fragment, public fun checkPermission (Ljava/lang/String;II)I public fun checkSelfPermission (Ljava/lang/String;)I protected fun getReactDelegate ()Lcom/facebook/react/ReactDelegate; + protected fun getReactHost ()Lcom/facebook/react/ReactHost; protected fun getReactNativeHost ()Lcom/facebook/react/ReactNativeHost; public fun onActivityResult (IILandroid/content/Intent;)V public fun onBackPressed ()Z diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactFragment.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactFragment.java index 894f46c06bc..b16f286f4f6 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactFragment.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactFragment.java @@ -17,6 +17,7 @@ import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; +import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags; import com.facebook.react.modules.core.PermissionAwareActivity; import com.facebook.react.modules.core.PermissionListener; @@ -80,9 +81,14 @@ public class ReactFragment extends Fragment implements PermissionAwareActivity { if (mainComponentName == null) { throw new IllegalStateException("Cannot loadApp if component name is null"); } - mReactDelegate = - new ReactDelegate( - getActivity(), getReactNativeHost(), mainComponentName, launchOptions, fabricEnabled); + if (ReactNativeFeatureFlags.enableBridgelessArchitecture()) { + mReactDelegate = + new ReactDelegate(getActivity(), getReactHost(), mainComponentName, launchOptions); + } else { + mReactDelegate = + new ReactDelegate( + getActivity(), getReactNativeHost(), mainComponentName, launchOptions, fabricEnabled); + } } /** @@ -92,8 +98,34 @@ public class ReactFragment extends Fragment implements PermissionAwareActivity { * implement {@code ReactApplication} or you simply have a different mechanism for storing a * {@code ReactNativeHost}, e.g. as a static field somewhere. */ + @Nullable protected ReactNativeHost getReactNativeHost() { - return ((ReactApplication) getActivity().getApplication()).getReactNativeHost(); + ReactApplication application = ((ReactApplication) getActivity().getApplication()); + if (application != null) { + return application.getReactNativeHost(); + } else { + return null; + } + } + + /** + * Get the {@link ReactHost} used by this app. By default, assumes {@link + * Activity#getApplication()} is an instance of {@link ReactApplication} and calls {@link + * ReactApplication#getReactHost()}. Override this method if your application class does not + * implement {@code ReactApplication} or you simply have a different mechanism for storing a + * {@code ReactHost}, e.g. as a static field somewhere. + * + *

If you're using Old Architecture/Bridge Mode, this method should return null as {@link + * ReactHost} is a Bridgeless-only concept. + */ + @Nullable + protected ReactHost getReactHost() { + ReactApplication application = ((ReactApplication) getActivity().getApplication()); + if (application != null) { + return application.getReactHost(); + } else { + return null; + } } protected ReactDelegate getReactDelegate() {