I use Jetpack Compose Navigation in my app.
- Compose Navigation version: 2.7.7
- lifecycleRuntimeKtx: 2.8.4
- Kotlin version: 1.9.25
- Device: Xiaomi 220333QNY
I have 2 screens: A, B.
The navigation graph looks like: A⟷B
Where → is navigate(route), and ← is navigateUp() or hardware back button.
I use ViewModel for screen A:
class MyViewModel(private val _openScreenB: () -> Unit) : ViewModel() {
fun openScreenB() {
_openScreenB()
}
}
NavContoller and NavHost:
setContent {
val navController = rememberNavController()
NavHost(
navController = navController,
...
) {
composable("ScreenA") {
val viewModel: MyViewModel = viewModel(
factory = MyViewModelFactory(
openScreenB = {
navController.navigate("ScreenB") {
launchSingleTop = true
}
}
)
)
ScreenA(
navigateToScreenB = {
viewModel.openScreenB()
}
)
}
composable("ScreenB") {
ScreenB(
navigateBack = {
navController.navigateUp()
}
)
}
}
}
Everything works fine until activity recreation (orientation change or switch light/dark mode). After recreation, line val navController = rememberNavController() is called again. The NavController recreates, and now navigateUp() does nothing, hardware back works, and navigate(route) crashes app with error.
java.lang.IllegalStateException: State must be at least CREATED to move to DESTROYED, but was INITIALIZED in component NavBackStackEntry(2d8f0727-c13b-4635-ac94-f279608c3cfc) destination=Destination(0x67884f5a) route=Editor
at androidx.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry.jvm.kt:131)
at androidx.lifecycle.LifecycleRegistry.setCurrentState(LifecycleRegistry.jvm.kt:107)
at androidx.navigation.NavBackStackEntry.updateState(NavBackStackEntry.kt:186)
at androidx.navigation.NavBackStackEntry.setMaxLifecycle(NavBackStackEntry.kt:159)
at androidx.navigation.NavController.updateBackStackLifecycle$navigation_runtime_release(NavController.kt:1100)
at androidx.navigation.NavController.dispatchOnDestinationChanged(NavController.kt:996)
at androidx.navigation.NavController.navigate(NavController.kt:1882)
at androidx.navigation.NavController.navigate(NavController.kt:1817)
at androidx.navigation.NavController.navigate(NavController.kt:2225)
at androidx.navigation.NavController.navigate$default(NavController.kt:2220)
at ...
I tried to navigate with saveState = true, restoreState = true, and launchSingleTop = true properties, but this doesn't fix the problem.
I also tried to use navController saveState() in onSaveInstanceState and restoreState(bundle) after rememberNavController, but it also doesn't help.