'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:
- Find a way, the entire
NavGraph
is saved persistently and restored - 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 |
---|