wix / react-native-navigation

A complete native navigation solution for React Native
https://wix.github.io/react-native-navigation/
MIT License
13.01k stars 2.68k forks source link

[v2] Tried to create view after it has already been destroyed #3767

Closed pibo closed 4 years ago

pibo commented 5 years ago

My app users are complaining about random crashes on Android. I have Crashlytics installed and I verified by using user and time filters that this crashes are caused by the following error:

captura de tela 2018-08-14 as 18 17 04

I can't reproduce the problem in the Android simulator and it seems Android exclusive, as it appears. Can anyone help me what might be happening? Thanks in advance.


Environment

nezaidu commented 5 years ago

same

nezaidu commented 5 years ago

somebody pls remember me to show you how to reproduce, i know how, very busy right now, might forget

starzle commented 5 years ago

See the same crash in Android only. In my case, it happens when a child screen is popping (the pop animation is running) when the setRoot() method is called. If I set the pop animation's duration to 0, it works without any problem. So I think the pop animation is the culprit here.

Hope this information can help you resolve the issue.

guyca commented 5 years ago

Unfortunately I can't fix this one without a reproduction, @nezaidu ?

reganperkins commented 5 years ago

getting the same thing but no consistent way of reproducing this.

guyca commented 5 years ago

@starzle Have you tried awaiting the pop command so root is set after pop completes?

starzle commented 5 years ago

@guyca In our case, the setRoot is called when componentDidAppear is triggered. And apparently, componentDidAppear is triggered before the pop animation ends. So we don't have a place where we can await the pop.

But if we simply add a delay to the setRoot call, then as long as the delay is long enough to make sure pop animation is already finish (onAnimationEnd called if I am correct) when setRoot is called, then the crash goes away. In short, pop's onAnimationEnd needs to be called before setRoot.

screen shot 2018-08-29 at 11 56 46 pm

Hope this info can help you.

suetming commented 5 years ago

after add code push relative, code push update restart app, android app will crash, logcat console out put this log

java.lang.RuntimeException: Tried to create view after it has already been destroyed

zirtuedeveloper commented 5 years ago

i have same issue

zirtuedeveloper commented 5 years ago
componentDidMount(){

  this._getDeviceToken();

  FCM.getInitialNotification().then(notif => {
    console.log(notif,'notif tapped')
    if (notif.gotoActivity==="dashboard") {
      startMainTab(2);
      return;
    }
    else if (notif.gotoActivity==="activity") {
      startMainTab(0);
      return;
    }

  });

  FCM.on(FCMEvent.Notification, this.handleNotification);

  this.tokenToState();

}
reganperkins commented 5 years ago

this also occurs when you have a root view, navigate to a new view with pushTo from a modal and then try to setStackRoot within the main application.

haggholm commented 5 years ago

To add to my colleague @reganperkins above, our error is the same but the stacktrace does not seem entirely identical.

09-19 14:13:26.303 5362-5362/co.elk.rn D/ERROR: java.lang.RuntimeException: Tried to create view after it has already been destroyed
        at com.reactnativenavigation.viewcontrollers.ViewController.getView(ViewController.java:153)
        at com.reactnativenavigation.viewcontrollers.ViewController.lambda$runOnPreDraw$2$ViewController(ViewController.java:266)
        at com.reactnativenavigation.viewcontrollers.ViewController$$Lambda$2.run(Unknown Source)
        at com.reactnativenavigation.utils.UiUtils$1.onPreDraw(UiUtils.java:27)
        at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:944)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2205)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1254)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6337)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:874)
        at android.view.Choreographer.doCallbacks(Choreographer.java:686)
        at android.view.Choreographer.doFrame(Choreographer.java:621)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:860)
        at android.os.Handler.handleCallback(Handler.java:751)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6119)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

We managed to find a workaround that may (or may not!) clarify the situation. As she was saying, the control flow in our scenario is this:

  1. Start on a root view.
  2. Open a modal (as it happens, to create a new item).
  3. From the modal, navigate via pushTo() to a new view (the new item).
  4. From the new item, navigate via setStackRoot() to the root component. (Of course, in this specific scenario, we could pop, but the code is more generic.)

The workaround: Close the modal before pushing the new view, deferring the push using setImmediate(). Now, for some reason, it no longer crashes. Perhaps the open modal does something strange to the stack?

DaneEveritt commented 5 years ago

I can confirm this happening as well. In my case I'm calling a setRoot on a login screen to bump an already logged in user into the app.

Heres the stack from the crash, only affects android devices.

E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: com.lawnlove.provider, PID: 17401
                  java.lang.RuntimeException: Tried to create view after it has already been destroyed
                      at com.reactnativenavigation.viewcontrollers.ViewController.getView(ViewController.java:152)
                      at com.reactnativenavigation.viewcontrollers.ParentController.getView(ParentController.java:63)
                      at com.reactnativenavigation.viewcontrollers.stack.StackController.lambda$push$4$StackController(StackController.java:157)
                      at com.reactnativenavigation.viewcontrollers.stack.StackController$$Lambda$4.run(Unknown Source:0)
                      at com.reactnativenavigation.anim.NavigationAnimator$1.onAnimationEnd(NavigationAnimator.java:64)
                      at android.animation.Animator$AnimatorListener.onAnimationEnd(Animator.java:552)
                      at android.animation.AnimatorSet.endAnimation(AnimatorSet.java:1293)
                      at android.animation.AnimatorSet.doAnimationFrame(AnimatorSet.java:1079)
                      at android.animation.AnimationHandler.doAnimationFrame(AnimationHandler.java:146)
                      at android.animation.AnimationHandler.-wrap2(Unknown Source:0)
                      at android.animation.AnimationHandler$1.doFrame(AnimationHandler.java:54)
                      at android.view.Choreographer$CallbackRecord.run(Choreographer.java:909)
                      at android.view.Choreographer.doCallbacks(Choreographer.java:723)
                      at android.view.Choreographer.doFrame(Choreographer.java:655)
                      at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
                      at android.os.Handler.handleCallback(Handler.java:789)
                      at android.os.Handler.dispatchMessage(Handler.java:98)
                      at android.os.Looper.loop(Looper.java:164)
                      at android.app.ActivityThread.main(ActivityThread.java:6944)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
E/UncaughtException: java.lang.RuntimeException: Tried to create view after it has already been destroyed
                         at com.reactnativenavigation.viewcontrollers.ViewController.getView(ViewController.java:152)
                         at com.reactnativenavigation.viewcontrollers.ParentController.getView(ParentController.java:63)
                         at com.reactnativenavigation.viewcontrollers.stack.StackController.lambda$push$4$StackController(StackController.java:157)
                         at com.reactnativenavigation.viewcontrollers.stack.StackController$$Lambda$4.run(Unknown Source:0)
                         at com.reactnativenavigation.anim.NavigationAnimator$1.onAnimationEnd(NavigationAnimator.java:64)
                         at android.animation.Animator$AnimatorListener.onAnimationEnd(Animator.java:552)
                         at android.animation.AnimatorSet.endAnimation(AnimatorSet.java:1293)
                         at android.animation.AnimatorSet.doAnimationFrame(AnimatorSet.java:1079)
                         at android.animation.AnimationHandler.doAnimationFrame(AnimationHandler.java:146)
                         at android.animation.AnimationHandler.-wrap2(Unknown Source:0)
                         at android.animation.AnimationHandler$1.doFrame(AnimationHandler.java:54)
                         at android.view.Choreographer$CallbackRecord.run(Choreographer.java:909)
                         at android.view.Choreographer.doCallbacks(Choreographer.java:723)
                         at android.view.Choreographer.doFrame(Choreographer.java:655)
                         at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
                         at android.os.Handler.handleCallback(Handler.java:789)
                         at android.os.Handler.dispatchMessage(Handler.java:98)
                         at android.os.Looper.loop(Looper.java:164)
                         at android.app.ActivityThread.main(ActivityThread.java:6944)
                         at java.lang.reflect.Method.invoke(Native Method)
                         at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
                         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
zsajjad commented 5 years ago

Any update on this @guyca ?

makirby commented 5 years ago

Wrapping the setStackroot calls with InteractionManager.runAfterInteractions, solved this for me.

zsajjad commented 5 years ago

@makirby can you please share a snippet for the solution?

makirby commented 5 years ago

Basically where we were making a setStackRoot call soon after another push in a modal stack, I would do something like this.

 InteractionManager.runAfterInteractions(() => {
                    Navigation.setStackRoot(STACK_IDS.main, {
                      component: { name: SCREEN_MAP.Home },
                    })
                  })
stale[bot] commented 5 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you believe the issue is still relevant, please test on the latest Detox and report back. Thank you for your contributions.

dozoisch commented 5 years ago

probably not stale

tzigdon commented 5 years ago

I also get this error randomly when existing the app via back button press and then re-entering the app

makirby's solution is not working in my case...

thalesgaldino commented 5 years ago

In my case, when I was calling setStackRoot twice(due to the component lifecycle), this crash was coming up in Android, but not is iOS. Then, to solve that, I made sure that method was only being called once. Hope that helps!

putuyoga commented 5 years ago

I can't reproduce this on emulator, but strangely able to reproduce this on physical device. When i show overlay and set stack root afterward and don't dismiss previous overlay, it will make above issue happens.

Snippet Code:

import { Navigation } from 'react-native-navigation';

const start = async () => {
  await Navigation.showOverlay(/* some arguments */);

  // to avoid crash, don't forget to dismiss overlay before call setStackRoot
  await Navigation.dismissOverlay(/* some arguments */);
  await Navigation.setStackRoot(/* some arguments */);
}
varungupta85 commented 5 years ago

Could somebody who is familiar with the internals of the code shed some light on some conditions when this error could occur. I am observing multiple of these errors in production with the below call stack after upgrading to v2. Since I am not able to reproduce this in my test setup, I am not sure where to start looking. I don't use setStackRoot in my app. I only have a single setRoot command in my app that starts the app.

java.lang.RuntimeException: Tried to create view after it has already been destroyed
    at com.reactnativenavigation.viewcontrollers.ViewController.getView(ViewController.java:161)
    at com.reactnativenavigation.viewcontrollers.stack.StackController.onAttachToParent(StackController.java:82)
    at com.reactnativenavigation.viewcontrollers.ViewController.onGlobalLayout(ViewController.java:251)
    at android.view.ViewTreeObserver.dispatchOnGlobalLayout(ViewTreeObserver.java:1013)
    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2823)
    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1863)
    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:8072)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)
    at android.view.Choreographer.doCallbacks(Choreographer.java:723)
    at android.view.Choreographer.doFrame(Choreographer.java:658)
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
    at android.os.Handler.handleCallback(Handler.java:790)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:7000)
    at java.lang.reflect.Method.invoke(Method.java)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:441)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1408)

cc @guyca @DanielZlotin

nilocoelhojunior commented 5 years ago

Same error here, but in my case, the error only occurs in android when I exit of the app using the back button.

java.lang.RuntimeException: Tried to create view after it has already been destroyed
  com.reactnativenavigation.viewcontrollers.ViewController.getView(ViewController.java:161)
  com.reactnativenavigation.viewcontrollers.stack.StackController.onAttachToParent(StackController.java:82)
  com.reactnativenavigation.viewcontrollers.ViewController.onGlobalLayout(ViewController.java:251)
  android.view.ViewTreeObserver.dispatchOnGlobalLayout(ViewTreeObserver.java:1013)
  android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2758)
  android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1843)
  android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7978)
  android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)
  android.view.Choreographer.doCallbacks(Choreographer.java:723)
  android.view.Choreographer.doFrame(Choreographer.java:658)
  android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
  android.os.Handler.handleCallback(Handler.java:790)
  android.os.Handler.dispatchMessage(Handler.java:99)
  android.os.Looper.loop(Looper.java:164)
  android.app.ActivityThread.main(ActivityThread.java:7000)
  java.lang.reflect.Method.invoke(Native Method)
  com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:441)
  com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1408)
varungupta85 commented 5 years ago

@nilocoelhojunior that is a great insight. So for you, is the abort happening when user exits the app and open it again or just during the process of exiting the app? If it is the latter, then does the user see The app has stopped error or not? Since I am not able to reproduce it locally, I am trying to understand as much about the issue as possible.

varungupta85 commented 5 years ago

I enhanced the log message to also include the id of the view in question. I updated the exception to throw new RuntimeException("Tried to create view after it has already been destroyed " + this.getId());. I found out that it is the first tab of the bottomTabs set as root of the app.

Why would we destroy the first tab of of the bottomTabs unless we are in the process of destroying the whole app and then why would we try to get it again?

el-lsan commented 5 years ago

I'm also facing this issue on release mode for Android devices. It happens when i'm changing screens a bit faster than normal use case.

Tried @makirby's solution but unfortunately didn't help.

lucasfalcaoo commented 5 years ago

Any solution @guyca ? I'm having the same error on Android... Here is my stacktrace:

java.lang.RuntimeException: Tried to create view after it has already been destroyed
        at com.reactnativenavigation.viewcontrollers.ViewController.getView(ViewController.java:153)
        at com.reactnativenavigation.viewcontrollers.stack.StackController.onAttachToParent(StackController.java:74)
        at com.reactnativenavigation.viewcontrollers.ViewController.onGlobalLayout(ViewController.java:243)
        at android.view.ViewTreeObserver.dispatchOnGlobalLayout(ViewTreeObserver.java:912)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1881)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1061)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5891)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
        at android.view.Choreographer.doCallbacks(Choreographer.java:580)
        at android.view.Choreographer.doFrame(Choreographer.java:550)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5298)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)
guyca commented 5 years ago

Hey guys, I wasn't able to reproduce the issue and the stack traces aren't indicating what the actual cause of the bug is. If anyone can PR a detox test that would be very helpful. Even a test where the crash happens some times and not consistently is good enough.

thalesgaldino commented 5 years ago

here is an example of crashing Android:

// sequencial calls to stackroot, very unlikely but happens for some workflow
Navigation.setStackRoot(...);
Navigation.setStackRoot(...);

only happens in Android(real device), when you are NOT debugging.

el-lsan commented 5 years ago

@guyca For my case it was happening when I was changing my screens using Navigation.setStackRoot(); It happens more often when I'm constantly changing the screens over and over, sometimes after 2-3 tries and sometimes needs more tries to reproduce it.

Based on my experience it happens pretty random but if you have heavier components to render in your screen (like FlatList or ListView with complicated items) it happens more often.

I just reproduced the bug using 2 simple screens. In each screen I'm invoking Navigation.setRoot(...) when topBar's rightButtons is pressed.

here's the screen record:

rnn crash produce

Bug report: image

So as temporary solution to avoid this, I ended up changing my logic and after changing Navigation.setStackRoot(...); to Navigation.push(...) this bug doesn't occur anymore.

FYI i'm using:

"react": "^16.8.3",
"react-native": "^0.58.6",
"react-native-navigation": "^2.13.1",

And as many mentioned:

only happens in real Android device on release mode.

harleenarora commented 5 years ago

If any one solved this issue, please provide me. I am already above solution but its not worked.

guyca commented 5 years ago

@el-lsan I believe #4843 will resolve that crash, Thanks @thalesgaldino for the reproduction.

@lucasfalcaojump How can I reproduce the crash?

@reganperkins @starzle I think #4842 will resolve your crash

lucasfalcaoo commented 5 years ago

@guyca I think I solved it. I was creating a stack object inside the "center" object on sideMenu's and inside the main component. When I took out the stack object from "center", it worked fine! Thanks for your solicitude!

My code became like this:

Navigation.setRoot({ root: { sideMenu: { left: { component: { name: 'navigation.SideMenu', } }, center: { component: { name: 'navigation.Map' } } }, stack: { children: [{ component: { name: "navigation.Map", }, }] } } });

crayssnlabs commented 5 years ago

I have the same structure and use the current master branch:

Navigation.setRoot({
    root: {
        sideMenu: {
            left: {
                component: {
                    name: SIDE_MENU,
                }
            },
            center: {
                stack: {
                    id: action.payload.stackName,
                    children: [
                        {
                            component: {
                                name: action.payload.pageName,
                                passProps: action.payload.passProps,
                            }
                        }
                    ]
                }
            }
        }
    }
});

The app crashed on android in release mode. I got the following stacktrace:

java.lang.RuntimeException: Tried to create view after it has already been destroyed
     at com.reactnativenavigation.viewcontrollers.ViewController.getView(ViewController.java:163)
     at com.reactnativenavigation.viewcontrollers.ChildController.onViewBroughtToFront(ChildController.java:45)
     at com.reactnativenavigation.viewcontrollers.ChildControllersRegistry.onViewDisappear(ChildControllersRegistry.java:15)
     at com.reactnativenavigation.viewcontrollers.ChildController.onViewDisappear(ChildController.java:41)
     at com.reactnativenavigation.viewcontrollers.ComponentViewController.onViewDisappear(ComponentViewController.java:48)
     at com.reactnativenavigation.viewcontrollers.ViewController.destroy(ViewController.java:233)
     at com.reactnativenavigation.viewcontrollers.ChildController.destroy(ChildController.java:70)
     at com.reactnativenavigation.viewcontrollers.ComponentViewController.destroy(ComponentViewController.java:93)
     at com.reactnativenavigation.viewcontrollers.ParentController.destroy(ParentController.java:112)
     at com.reactnativenavigation.viewcontrollers.navigator.Navigator.destroyRoot(Navigator.java:121)
     at com.reactnativenavigation.viewcontrollers.navigator.Navigator.setRoot(Navigator.java:131)
     at com.reactnativenavigation.react.NavigationModule.lambda$setRoot$1(NavigationModule.java:70)
     at com.reactnativenavigation.react.-$$Lambda$NavigationModule$IfiDeOnYfgJADKZUxIVN9Zforsw.run(Unknown Source:8)
     at android.os.Handler.handleCallback(Handler.java:873)
     at android.os.Handler.dispatchMessage(Handler.java:99)
     at android.os.Looper.loop(Looper.java:193)
     at android.app.ActivityThread.main(ActivityThread.java:6762)
     at java.lang.reflect.Method.invoke(Native Method)
     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

Update:

It occurs when i use the back button to leave the app.

guyca commented 5 years ago

@crayssnlabs Couldn't reproduce the crash in the playground app. Please fork the repo and push a reproduction to the playground app in your fork.

alvarorc commented 5 years ago

It may look silly but I had facing the same issue. The problem in my case was that I was trying to set the root twice in a componentWillMount call. Here is my example code for the Initializing component:

class Initializing extends PureComponent {
  componentDidMount() {
    const { isAuthenticated, goToHome, goToAuth } = this.props;

    if (isAuthenticated) {
      // should be returning here to prevent call goToAuth
      return goToHome();
    }

    goToAuth();
  }

  render() {
    return (
      <View style={{ justifyContent: 'center', alignItems: 'center' }}>
        <ActivityIndicator />
      </View>
    );
  }
}

And the functions goToHome and gotToAuth are just wrappers for set Navigation.setRoot

zabojad commented 5 years ago

I'm having the same crash at the startup of my app (both debug and release) on Android only.

It was happening on 3 startups out of 4 (very annoying...) with RNN version 2.7.1 and it seems to happen all the time with RNN version 2.15.0.

I've just updated to latest 2.15.0version of RNN hoping it would solve it but no, I'm still having those crashes. What can I do to help you find a fix?

My stacktrace:

03-22 22:40:37.346 13645-13645/blablabla E/AndroidRuntime: FATAL EXCEPTION: main
    Process: blablabla, PID: 13645
    java.lang.RuntimeException: Tried to create view after it has already been destroyed
        at com.reactnativenavigation.viewcontrollers.ViewController.getView(ViewController.java:163)
        at com.reactnativenavigation.viewcontrollers.stack.StackController.onAttachToParent(StackController.java:82)
        at com.reactnativenavigation.viewcontrollers.ViewController.onGlobalLayout(ViewController.java:253)
        at android.view.ViewTreeObserver.dispatchOnGlobalLayout(ViewTreeObserver.java:1013)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2679)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1779)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7810)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)
        at android.view.Choreographer.doCallbacks(Choreographer.java:723)
        at android.view.Choreographer.doFrame(Choreographer.java:658)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
        at android.os.Handler.handleCallback(Handler.java:789)
        at android.os.Handler.dispatchMessage(Handler.java:98)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6938)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
zabojad commented 5 years ago

After some attempts to isolate the cause of the crash, I've found out that it is caused by the Navigation.events().bindComponent(this) I have in the constructor of my HomePage component. If I comment it, I have no crash anymore (the problem is that I need it).

I'll play a little bit with delaying this call and so on to see if I can workaround it... However, that sounds like a beginning of a track to investigate on the real causes of the issue, doesn't it?

My main layout looks like that:

Navigation.setRoot({
    root: {
        sideMenu: {
            left: {
                component: {
                    id: IDs.DRAWER,
                    name: SideMenu,
                }
            },
            center: {
                stack: {
                    id: IDs.MAIN_STACK,
                    children: [{
                        component: {
                            name: HomePage
                        },  
                    }],
                }
            },
        },
    }
});
zabojad commented 5 years ago

Yhea as I thought, if I delay it (3000ms delay), no crash is happening... With a 1000 ms delay, it can happen in debug mode (not always).

guyca commented 5 years ago

@zabojad Can you please PR a filing detox text? Or push a branch where this issue reproduces in the playground app

zabojad commented 5 years ago

@guyca After more debugging, I've realized this issue happens because I had a call to setState in the componentDidAppear method of my component. I can easily workaround it in my code now that I know that this causes the issue.

However... Should it be considered as a RNN bug?

guyca commented 5 years ago

Interesting 🤔 Seems like something RNN should be able to handle, could you please PR a failing detox test? Or even a branch of the playground app with reproduction steps. Would really like to look into this more.

kyle-ssg commented 5 years ago

Can confirm I've just started facing this, thanks for the catch @zabojad 👍. This seems to be Android only.

Edit: This was actually my own fault (although the hard crash without indication wasn't ideal). This is also replicable on android if you try to push to a screen twice from the same component id. iOS side silently deals with it.

bahmannejati commented 5 years ago

Here is my code for reproduce this issue & also found tricks to solve the issue :

for(let i = 0; i < 20; i++){
    Navigation.setRoot({
        root: {
            component: {
                id: SCREENS.HUB,
                name: SCREENS.HUB,

                passProps: {
                }
            }
        }
    });
    Navigation.setRoot({
        root: {
            sideMenu: {
                center: {
                    stack: {
                        children: [
                            {
                                component: {
                                    id: SCREENS.HOME,
                                    name: SCREENS.HOME,
                                }
                            }
                        ],
                    }
                },
                right: {
                    component: {
                        id: SCREENS.SIDE_MENU,
                        name: SCREENS.SIDE_MENU,
                    }
                }
            }
        }
    });
}

I placed 20 in for() to make sure that error happens, because this issue doesn't happen always. After about 3 days and testing many solutions (that no one worked correctly, even i made a task queue system for managing Navigation methods priority in a good way) i found that cant fix that permanently.

But we have two choice to get rid out of that:

1. Making app layout structure with just 1 Navigation.setRoot() and then use .push() .pop() .popToRoot() to manage navigation, it should work but still is risky because i faced Tried to create... even in my first Navigation.setRoot()

2. Simply comment (or delete :) bellow line in ViewController.java:

if (isDestroyed) {
      throw new RuntimeException("Tried to create view after it has already been destroyed");
}

This worked for me without any problem, that is a quick TEMPORARY solution, not PERMANENTLY.

(ViewController.java is here : /node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/)

Zaporozhec7 commented 5 years ago

If I try use method 2. mentioned by @bahmannejati , I have segfault instead that exception

nilocoelhojunior commented 5 years ago

Sorry @varungupta85 for delay. In my case, I have two navigations one Stack and one with BotoomTabs. And to manage this navigation I have a Component with Redux. What happened was that this component was updated more than once by Redux and with that, the setRoot was also called and the app crashed. The solution was to create an attribute in the state of the Component to control when to call the setRoot.

fodjan-philip commented 5 years ago

My app consists of BottomTabs containing stacks of screens. Whenever the BottomTab is changed, I call Navigation.popToRoot() for the tab that the user is leaving.

I can reproduce the crash by pushing a screen to the stack of a tab (with waitForRender in push animation) and then quickly changing to another tab and back.

It sounds like https://github.com/wix/react-native-navigation/pull/4842 addressed that issue, but I am running v2.16.0 and still get the error.

guyca commented 5 years ago

@fliPmitKlammern Could you please push a branch with a reproduction in the playground app?

RuairiOliver commented 5 years ago

Got this today, going with commenting it out for now as suggested earlier