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

Closed
gmantuanrosa opened this issue Sep 18, 2024 · 7 comments
Closed
Labels
Platform: Android Android applications. Resolution: PR Submitted A pull request with a fix has been provided. 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

cortinico added a commit to cortinico/react-native that referenced this issue Sep 24, 2024
Summary:
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 facebook#46566

Changelog:
[Android] [Fixed] - ReactFragment should properly instantiate ReactDelegate on Bridgeless

Differential Revision: D63319977
cortinico added a commit to cortinico/react-native that referenced this issue Sep 26, 2024
…facebook#46623)

Summary:
Pull Request resolved: facebook#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 facebook#46566

Changelog:
[Android] [Fixed] - ReactFragment should properly instantiate ReactDelegate on Bridgeless

Reviewed By: mdvacca

Differential Revision: D63319977
cortinico added a commit to cortinico/react-native that referenced this issue Sep 26, 2024
Summary:
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 facebook#46566

Changelog:
[Android] [Fixed] - ReactFragment should properly instantiate ReactDelegate on Bridgeless

Differential Revision: D63319977
cortinico added a commit to cortinico/react-native that referenced this issue Sep 26, 2024
…tentView`

Summary:
Fixes facebook#46566

Currently `ReactFragment` and `ReactDelegate` don't work in OSS + New Architecture because we call `Activity.setContentView`
on the host activity.

That result on us replacing the whole activity layout, even when the user wants to use a Fragment.
As we do have `ReactActivityDelegate` that already does this:
https://github.com/facebook/react-native/blob/94b77938435693792e57c96d76691d58d7361530/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactActivityDelegate.java#L138

So this call is unncessary.

I've also updated the relative documentation here:
facebook/react-native-website#4232

Changelog:
[Android] [Fixed] - fix: ReactDelegate/ReactFragment crashing on New Architecture apps

Differential Revision: D63464367
@cortinico
Copy link
Contributor

I've spent more time on this and finally fixed it.

  1. The docs are udpated here: Fully revamp the 'Integration with an Android Fragment' page react-native-website#4232
  2. Those two PR will fix your issue:
    1. ReactFragment should properly instantiate ReactDelegate on Bridgeless #46623
    2. ReactFragment should properly instantiate ReactDelegate on Bridgeless #46623

I've opened a Pick request for those fixes to be included inside 0.76 here:

@cortinico cortinico added Resolution: PR Submitted A pull request with a fix has been provided. Platform: Android Android applications. and removed Needs: React Native Team Attention labels Sep 26, 2024
cortinico added a commit to cortinico/react-native that referenced this issue Sep 26, 2024
Summary:
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 facebook#46566

Changelog:
[Android] [Fixed] - ReactFragment should properly instantiate ReactDelegate on Bridgeless

Differential Revision: D63319977
cortinico added a commit to cortinico/react-native that referenced this issue Sep 26, 2024
…tentView` (facebook#46671)

Summary:
Pull Request resolved: facebook#46671

Fixes facebook#46566

Currently `ReactFragment` and `ReactDelegate` don't work in OSS + New Architecture because we call `Activity.setContentView`
on the host activity.

That result on us replacing the whole activity layout, even when the user wants to use a Fragment.
As we do have `ReactActivityDelegate` that already does this:
https://github.com/facebook/react-native/blob/94b77938435693792e57c96d76691d58d7361530/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactActivityDelegate.java#L138

So this call is unncessary.

I've also updated the relative documentation here:
facebook/react-native-website#4232

Changelog:
[Android] [Fixed] - fix: ReactDelegate/ReactFragment crashing on New Architecture apps

Reviewed By: rozele

Differential Revision: D63464367
cortinico added a commit to cortinico/react-native that referenced this issue Sep 26, 2024
…facebook#46623)

Summary:
Pull Request resolved: facebook#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 facebook#46566

Changelog:
[Android] [Fixed] - ReactFragment should properly instantiate ReactDelegate on Bridgeless

Reviewed By: mdvacca

Differential Revision: D63319977
facebook-github-bot pushed a commit that referenced this issue Sep 27, 2024
…tentView` (#46671)

Summary:
Pull Request resolved: #46671

Fixes #46566

Currently `ReactFragment` and `ReactDelegate` don't work in OSS + New Architecture because we call `Activity.setContentView`
on the host activity.

That result on us replacing the whole activity layout, even when the user wants to use a Fragment.
As we do have `ReactActivityDelegate` that already does this:
https://github.com/facebook/react-native/blob/94b77938435693792e57c96d76691d58d7361530/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactActivityDelegate.java#L138

So this call is unncessary.

I've also updated the relative documentation here:
facebook/react-native-website#4232

Changelog:
[Android] [Fixed] - fix: ReactDelegate/ReactFragment crashing on New Architecture apps

Reviewed By: rozele

Differential Revision: D63464367

fbshipit-source-id: acbfbf7d68eb79657b811a5a9a0d3f72660ec94a
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Platform: Android Android applications. Resolution: PR Submitted A pull request with a fix has been provided. Type: New Architecture Issues and PRs related to new architecture (Fabric/Turbo Modules)
Projects
None yet
4 participants