Ignoring navigate() call: FragmentManager has already saved its state
B

5

22

I'm using navigation in MainActivity, then I start SecondActivity (for result). After finish of SecondActivity I would like to continue with navigation in MainActivity, but FragmentManager has saved his state already.

On Navigation.findNavController(view).navigate(R.id.action_next, bundle) I receive log message:

Ignoring navigate() call: FragmentManager has already saved its state

How I can continue in navigation?

Bioplasm answered 17/8, 2018 at 12:15 Comment(7)
Where are you calling the navigate method from?Fillender
@Fillender I call navigate from Fragment of first Activity, when onActivityResult is called in the parent Activity.Bioplasm
Have you tried calling startActivityForResult and overriding onActivityResult in the Fragment directly?Fillender
@Fillender yes, i tried, but there is problem when first activity is restarted (orientation change) during processing second activity (result is not called on fragment of restarted activity)Bioplasm
How are you triggering the navigate call in the fragment? If you're consuming the result in the Activity can you not just navigate directly from there - e.g. by using something like Navigation.findNavController(this.findViewById(R.id.nav_host)) - where nav_host is your NavHostFragmentFillender
@Fillender there is listener for result call in fragment used (so the result is promoted to the fragment). This solution is described here: https://mcmap.net/q/589231/-fragment-39-s-onactivityresult-not-called-after-orientation-changeBioplasm
Have you found solution for this issue @FrancisNovotný?Butch
H
10

You must always call super.onActivityResult() in your Activity's onActivityResult. That is what:

  1. Unlocks Fragments so they can do fragment transactions (i.e., avoid the state is already saved errors)

  2. Dispatches onActivityResult callbacks to Fragments that called startActivityForResult.

Henriques answered 8/3, 2019 at 18:56 Comment(3)
I've filed this issue to track adding @CallSuper to FragmentActivity's onActivityResultHenriques
This fixed it for me!Boomer
Welp moving super.ondestroy to the top of the function solved a lot of things for me. Thank you dude!Millicent
B
7

Finally, I fix the issue by simple calling super.onPostResume() right before navigating to restore state.

Bioplasm answered 17/1, 2019 at 9:45 Comment(3)
this helped me tooSarcous
What do you mean by navigating to restore state, can you please clarify because i am also having similar issue but not sure where need to call this super.onPostResume()?Petula
@francis Can you provide some code?Guatemala
C
2

I believe above solutions should work. But my problem was different. There was a third party sdk which was launching its activity using context provided by me and it was delivering the result on a listener which I had to implement.

So there was no option for me to work with onActivityResult :(

I used below hack to solve the issue:

   private var runnable: Runnable? = null // Runnable object to contain the navigation code

    override fun onResume() {
        super.onResume()

        // run any task waiting for this fragment to be resumed
        runnable?.run()
    }


    override fun responseListener(response: Response) {    // Function in which you are getting response

        if (!isResumed) {    
            // add navigation to runnable as fragment is not resumed
            runnable = Runnable {
                navController.navigate(R.id.destination_to_navigate)
            }
        } else {
            // navigate normally as fragment is already resumed
            navController.navigate(R.id.destination_to_navigate)
        }
    }


Let me know if there is any better solution for this. Currently I found this very simple and easy to implement :)

Cipolin answered 3/1, 2020 at 6:48 Comment(1)
works nice, just add runnable = null after navigating in the Runnable block, otherwise you'll navigate at each app resume.Oppilate
F
1

I've solved this problem this way:

    @Override
public void onActivityResult() { //inside my fragment that started activity for result
        model.navigateToResults = true; //set flag, that navigation should be performed
}

and then

    @Override
public void onResume() { //inside fragment that started activity for result
    super.onResume();

    if(model.navigateToResults){
        model.navigateToResults = false;
        navController.navigate(R.id.action_startFragment_to_resultsFragment);
    }
}

not sure, if this is not a terrible hack, but it worked for me. FramgentManager state is restored at this point (onResume) and no problems with navigation occur.

Fernandez answered 30/11, 2018 at 9:18 Comment(2)
I also experienced the problem when using a LiveData observable instead of onActivityResult to communicate navigation events between an Activity and another Activity with Fragments. The solution to perform navigation in onResume worked perfectlyLithographer
There's no way since using navigation component in android < 21. Thank youYiddish
G
0

call super.onPostResume() before navigation....It's working

Grunberg answered 9/3, 2020 at 10:32 Comment(1)
Hi shashank, this answer has already been posted nearly word for word by the original question poster.Scenography

© 2022 - 2024 — McMap. All rights reserved.