From my understanding of navigation graph scoped view models, their onCleared
method should get called immediately when the associated navigation graph is popped from the navigation stack. What I'm seeing is that it takes a couple more navigate calls, until onCleared
is actually getting called.
Inside MainActivity.kt:
val swipeDismissableNavController = rememberSwipeDismissableNavController()
swipeDismissableNavController.addOnDestinationChangedListener(NavController.OnDestinationChangedListener { controller, destination, arguments ->
try {
controller.getBackStackEntry("chat")
} catch(e: IllegalArgumentException) {
Log.d(TAG, "Not on stack")
}
Log.d(TAG, "Route: " + destination.route)
})
SwipeDismissableNavHost(
navController = swipeDismissableNavController,
startDestination = "home"
) {
navigation(
startDestination = "messages",
route = "chat"
) {
composable(
route = "messages"
) {
val backStackEntry = remember { swipeDismissableNavController.getBackStackEntry("chat") }
val chatViewModel: ChatViewModel = viewModel(backStackEntry)
...
}
composable(
route = "image"
) {
val backStackEntry = remember { swipeDismissableNavController.getBackStackEntry("chat") }
val chatViewModel: ChatViewModel = viewModel(backStackEntry)
...
}
}
...
}
Inside ChatViewModel.kt
class ChatViewModel(): ViewModel() {
...
init {
Log.d(TAG, "init")
}
override fun onCleared() {
super.onCleared()
Log.d(TAG, "onCleared")
}
}
What I am observing is the following behavior:
When I navigate to chat
, the view model is correctly created printing init
. By navigating inside the chat
graph, the view model instance is correctly reused.
However, when I'm navigating out of the chat
graph, I'm seeing that Not on stack
is getting printed, but onCleared
is not. Only after some additional navigations, onCleared
is getting printed eventually.
Does anyone have an idea why onCleared
is getting called delayed?
The print stack looks something like:
Not on Stack
Route: home
Route: messages
init
Not on Stack
Route: home
** (THIS IS WHERE I WOULD EXPECT TO SEE onCleared) **
Not on Stack
Route: settings
Not on Stack
Route: home
onCleared
However, if I'm doing more navigations inside the chat
graph, onCleared
is getting called correctly:
Not on Stack
Route: home
Route: messages
init
Route: image
Route: messages
Route: image
Route: messages
Route: image
Route: messages
Not on Stack
Route: home
onCleared