Search code examples
androidandroid-jetpackandroid-architecture-navigation

Fragment instance dissapear when app is in background


I have an app that contains DrawerLayout and Navigation Component.

Listener is set with NavigationItemSelectedListener instead of the setupWithNavController because I want to handle the instances of Fragment instead of recreating/replacing over and over

When I press back in Fragment A it leaves the app in "background mode" (That's normal) and when I return to the app and go from FRAGMENT A TO FRAGMENT B it destroys the FRAGMENT A AND THE VIEWMODEL and now I can't get the instance of that fragment doing a popBackStack().

Something I noticed is that when the app goes in the background, the backstack of navController is cleaned, therefore once I get back to the app the fragment where I left (Fragment A) will be destroyed once I navigate to another fragment and I can't get back that instance.

This is gets super difficult because I just want to handle the instances of the fragments but it just creates a new one. And the popbackStack can't find the old fragment once the APP is in background so I don't know what I can do.

If I set an action in the nav graph from Fragment_A to Fragment_B, after leaving the app and re-entering and navigating to Fragment_B it appears an error: action_fragmentA_to_fragmentB cannot be found from the current destination NavGraph

I just have a custom onBackPressed in Fragment A to leave the app using.

fun defaultOnBackPressed() {
    if (findNavController().popBackStack().not()) {
        requireActivity().moveTaskToBack(true)
    } else {
        findNavController().popBackStack()
    }
}

What should I do?

It's been 2 days since I've been trying to solve this, but I can't get to solve something so complex that imo should be easy. I have tried a lot of solutions. Feel free to request any code.


Solution

  • you need to change your if statement. you are calling popBackstack() function while you are checking if statement and it pops. you can replace your statement as either:

    fun defaultOnBackPressed() {
        if (requireActivity().supportFragmentManager.fragments.size() == 1) {
            requireActivity().moveTaskToBack(true)
        } else {
            findNavController().popBackStack()
        }
    }
    

    Or

    fun defaultOnBackPressed() {
        if (requireActivity().supportFragmentManager.backStackEntryCount == 1) {
            requireActivity().moveTaskToBack(true)
        } else {
            findNavController().popBackStack()
        }
    }