Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Brownfield app crashes when using ReactFragment on new architecture #46566

Open
gmantuanrosa opened this issue Sep 18, 2024 · 6 comments
Open
Labels
Needs: Triage 🔍 Type: New Architecture Issues and PRs related to new architecture (Fabric/Turbo Modules)

Comments

@gmantuanrosa
Copy link

Description

I have an Android app that is using React Native for some activities and I decided to follow React Native documentation to add into Fragments as well. My App has a mix of XML and Compose navigation and Fragments for the Bottom Tab Navigation -- one of the tab being React Native.

It does work fine until I enable the new architecture, generating app crashes once the Fragment is mounted. I also had the same issue creating a custom Activity with the same crash behavior.

Steps to reproduce

  1. Create a new Android Project;
  2. Integrate React Native following the documentation;
  3. Create an Android Fragment;
  4. Integrate React Fragment into Android Fragment;
  5. Init the App and launch the Fragment [ FAILED ]

React Native Version

0.75.3

Affected Platforms

Runtime - Android

Output of npx react-native info

command not found even running `npx @react-native-community/cli info`

Stacktrace or Logs

E  FATAL EXCEPTION: main
          Process: com.example.composereactnativeapp, PID: 15959
          java.lang.NullPointerException: Attempt to invoke interface method 'com.facebook.react.interfaces.fabric.ReactSurface com.facebook.react.ReactHost.createSurface(android.content.Context, java.lang.String, android.os.Bundle)' on a null object reference
           at com.facebook.react.ReactDelegate.loadApp(ReactDelegate.java:283)
           at com.facebook.react.ReactDelegate.loadApp(ReactDelegate.java:275)
           at com.facebook.react.ReactFragment.onCreateView(ReactFragment.java:95)
           at androidx.fragment.app.Fragment.performCreateView(Fragment.java:3119)
           at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:577)
           at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:286)
           at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2164)
           at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:2059)
           at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:2002)
           at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3277)
           at androidx.fragment.app.FragmentManager.dispatchViewCreated(FragmentManager.java:3180)
           at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:3153)
           at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:608)
           at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:286)
           at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2164)
           at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:2059)
           at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:2002)
           at androidx.fragment.app.FragmentManager$5.run(FragmentManager.java:702)
           at android.os.Handler.handleCallback(Handler.java:938)
           at android.os.Handler.dispatchMessage(Handler.java:99)
           at android.os.Looper.loopOnce(Looper.java:201)
           at android.os.Looper.loop(Looper.java:288)
           at android.app.ActivityThread.main(ActivityThread.java:7870)
           at java.lang.reflect.Method.invoke(Native Method)
           at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
           at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)

Reproducer

https://github.com/gmantuanrosa/brownfield-rn-fragment

Screenshots and Videos

No response

@Sky
Copy link

Sky commented Sep 18, 2024

Have the same issue when just trying to enable New Architecture on existing project. RN 0.75.3

FATAL EXCEPTION: main
        Process: com.***, PID: 12871
        java.lang.RuntimeException: Unable to start activity ComponentInfo{com.***/com.***.AppActivity}: java.lang.NullPointerException: Attempt to invoke interface method 'com.facebook.react.interfaces.fabric.ReactSurface com.facebook.react.ReactHost.createSurface(android.content.Context, java.lang.String, android.os.Bundle)' on a null object reference
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3449)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7656)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
        Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'com.facebook.react.interfaces.fabric.ReactSurface com.facebook.react.ReactHost.createSurface(android.content.Context, java.lang.String, android.os.Bundle)' on a null object reference
        at com.facebook.react.ReactDelegate.loadApp(ReactDelegate.java:283)
        at com.facebook.react.ReactActivityDelegate.loadApp(ReactActivityDelegate.java:137)
        at com.facebook.react.ReactActivityDelegate.onCreate(ReactActivityDelegate.java:132)
        at com.facebook.react.ReactActivity.onCreate(ReactActivity.java:47)
        at com.***.AppActivity.onCreate(AppActivity.java:30)
        at android.app.Activity.performCreate(Activity.java:7994)
        at android.app.Activity.performCreate(Activity.java:7978)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3422)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loop(Looper.java:223) 
        at android.app.ActivityThread.main(ActivityThread.java:7656) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

@cipolleschi cipolleschi added the Type: New Architecture Issues and PRs related to new architecture (Fabric/Turbo Modules) label Sep 19, 2024
@cortinico
Copy link
Contributor

Thanks for attaching a reproducer @gmantuanrosa

There is a bug inside ReactFragment that I need to fix in order for this to work properly. I'll get back to you

@gmantuanrosa
Copy link
Author

Thanks for attaching a reproducer @gmantuanrosa

There is a bug inside ReactFragment that I need to fix in order for this to work properly. I'll get back to you

Thanks to look into it @cortinico!

I had the same issue when using Activity as well (also mentioned by @Sky). Probably because they share the same ReactDelegate?

Can you say that this will also fix Activity issues? If you want I can update the repro to have a React Activity being launched as well 😄

@cortinico
Copy link
Contributor

Can you say that this will also fix Activity issues? If you want I can update the repro to have a React Activity being launched as well 😄

Yes please. I'd say we first need to fix the Activity scenario, and then get back to the Fragment one. If you could update the repo to use activities instead, it would be extremely helpful

@gmantuanrosa
Copy link
Author

Can you say that this will also fix Activity issues? If you want I can update the repro to have a React Activity being launched as well 😄

Yes please. I'd say we first need to fix the Activity scenario, and then get back to the Fragment one. If you could update the repo to use activities instead, it would be extremely helpful

Fortunately I could make it work the Fabric React Activity but there is now an example in the reproducible, I still can't make Fragments work.

Also I only got this activity issue once and I don't know how can I reproduce it again.

@cortinico
Copy link
Contributor

Ok so sharing my findings so far (perhaps they'll help you @gmantuanrosa) but I need to get back to this next week.

  1. ReactFragment as it is at the moment is not properly creating the ReactDelegate. When on Bridgeless, you need to have a valid ReactHost instance as otherwise the app will crash as you're seeing.

  2. The patch to circumvent this is to do the following:

  3. Enable build from source in your project https://reactnative.dev/contributing/how-to-build-from-source

  4. Downgrade AGP to 8.5.0 (this is needed only because of the build from source).

  5. Edit the ReactFragment.java here as follows:

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String mainComponentName = null;
Bundle launchOptions = null;
Boolean fabricEnabled = null;
if (getArguments() != null) {
mainComponentName = getArguments().getString(ARG_COMPONENT_NAME);
launchOptions = getArguments().getBundle(ARG_LAUNCH_OPTIONS);
fabricEnabled = getArguments().getBoolean(ARG_FABRIC_ENABLED);
}
if (mainComponentName == null) {
throw new IllegalStateException("Cannot loadApp if component name is null");
}
mReactDelegate =
new ReactDelegate(
getActivity(), getReactNativeHost(), mainComponentName, launchOptions, fabricEnabled);
}

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    String mainComponentName = null;
    Bundle launchOptions = null;
    Boolean fabricEnabled = null;
    if (getArguments() != null) {
      mainComponentName = getArguments().getString(ARG_COMPONENT_NAME);
      launchOptions = getArguments().getBundle(ARG_LAUNCH_OPTIONS);
      fabricEnabled = getArguments().getBoolean(ARG_FABRIC_ENABLED);
    }
    if (mainComponentName == null) {
      throw new IllegalStateException("Cannot loadApp if component name is null");
    }
    if (!ReactFeatureFlags.enableBridgelessArchitecture) {
      mReactDelegate =
              new ReactDelegate(
                      getActivity(), getReactNativeHost(), mainComponentName, launchOptions, fabricEnabled);
    } else {
      mReactDelegate =
              new ReactDelegate(
                      getActivity(), getReactHost(), mainComponentName, launchOptions);
    }
  }

  private ReactHost getReactHost() {
    return ((ReactApplication) getActivity().getApplication()).getReactHost();
  }

You will then observe that the app crashes with a different crash:

java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first

Full stacktrace:

09-20 17:28:48.351 18853 18853 E AndroidRuntime: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
09-20 17:28:48.351 18853 18853 E AndroidRuntime: 	at android.view.ViewGroup.addViewInner(ViewGroup.java:5247)
09-20 17:28:48.351 18853 18853 E AndroidRuntime: 	at android.view.ViewGroup.addView(ViewGroup.java:5076)
09-20 17:28:48.351 18853 18853 E AndroidRuntime: 	at androidx.fragment.app.FragmentContainerView.addView(FragmentContainerView.kt:269)
09-20 17:28:48.351 18853 18853 E AndroidRuntime: 	at android.view.ViewGroup.addView(ViewGroup.java:5016)
09-20 17:28:48.351 18853 18853 E AndroidRuntime: 	at androidx.fragment.app.FragmentStateManager.addViewToContainer(FragmentStateManager.java:901)
09-20 17:28:48.351 18853 18853 E AndroidRuntime: 	at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:585)
09-20 17:28:48.351 18853 18853 E AndroidRuntime: 	at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:286)
09-20 17:28:48.351 18853 18853 E AndroidRuntime: 	at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2164)
09-20 17:28:48.351 18853 18853 E AndroidRuntime: 	at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:2059)
09-20 17:28:48.351 18853 18853 E AndroidRuntime: 	at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:2002)
09-20 17:28:48.351 18853 18853 E AndroidRuntime: 	at androidx.fragment.app.FragmentManager$5.run(FragmentManager.java:702)
09-20 17:28:48.351 18853 18853 E AndroidRuntime: 	at android.os.Handler.handleCallback(Handler.java:938)
09-20 17:28:48.351 18853 18853 E AndroidRuntime: 	at android.os.Handler.dispatchMessage(Handler.java:99)
09-20 17:28:48.351 18853 18853 E AndroidRuntime: 	at android.os.Looper.loopOnce(Looper.java:201)
09-20 17:28:48.351 18853 18853 E AndroidRuntime: 	at android.os.Looper.loop(Looper.java:288)
09-20 17:28:48.351 18853 18853 E AndroidRuntime: 	at android.app.ActivityThread.main(ActivityThread.java:7842)
09-20 17:28:48.351 18853 18853 E AndroidRuntime: 	at java.lang.reflect.Method.invoke(Native Method)
09-20 17:28:48.351 18853 18853 E AndroidRuntime: 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
09-20 17:28:48.351 18853 18853 E AndroidRuntime: 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
09-20 17:28:48.352 12150 14336 W ActivityTaskManager:   Force finishing activity com.example.composereactnativeapp/.activity.MainActivity

I haven't been able to isolate why is it crashing with this error. It can either be because of the NavHost from Jetpack Compose or it can be a bug inside React Native.

Any investigation is more than appreciated @gmantuanrosa

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs: Triage 🔍 Type: New Architecture Issues and PRs related to new architecture (Fabric/Turbo Modules)
Projects
None yet
Development

No branches or pull requests

4 participants