'NavGraph with dynamic destinations - restore after process kill

This is the setup:

  • View-based Android UI
  • Using androidx.navigation library (tested with versions 2.4.1 and 2.5.0-beta01)
  • Activity, consisting of a bottom bar and a NavHostFragment

What's special is that the navigation structure is defined by the server. The top-level destinations are available during Activity.onCreate(). Other detail screens (=children of the top-level destinations) are only known when performing more server calls while navigating down in the hierarchy.

This is an excerpt of the body of Activity.onCreate():

val navController = findNavController(R.id.navigationHostFragment)

val topLevelDestinations = getTopLevelDestinations()

// some additional destinations are defined statically in navigation.xml (e.g. settings)
val staticNavGraph = navInflater.inflate(R.navigation.navigation)

graph = staticNavGraph.apply {
    setStartDestination(topLevelDestinations.first())
    addDynamicDestinations(staticNavGraph, topLevelDestinations)
}

This code works initially. The NavGraph contains the top-level destinations.

Some top-level destinations offer navigation to children elements. These destinations are added to the NavGraph in a just-in-time manner, i.e. just before navigate() is called.

When the user navigated to a detail screen, the app process is killed and the app is re-opened, then onCreate() is called again and the app crashes during setGraph()/graph = with the following error:

java.lang.IllegalStateException: Restoring the Navigation back stack failed: destination -1178236840 cannot be found from the current destination Destination(0x1a356ec2) ...
        at androidx.navigation.NavController.onGraphCreated(NavController.kt:1128)
        at androidx.navigation.NavController.setGraph(NavController.kt:1086)
        at androidx.navigation.NavController.setGraph(NavController.kt:100)

To solve this I'd be fine with either of these options:

  1. Find a way, the entire NavGraph is saved persistently and restored
  2. Prevent NavController from trying to recover the last destination, but show the initial start destination again.

Regarding 2. I tried calling navController.popBackStack(startDestination, false) and navController.clearBackStack(startDestination) before setGraph() is called but this doesn't seem to have the desired effect.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source