Tin Tran
07/23/2021, 6:28 AMnavigation-compose:2.4.0-alpha05
my view model init {}
is called continuously. Does anyone having the same issue?
I’m using hilt-navigation-compose:1.0.0-alpha03
julioromano
07/23/2021, 7:20 AMTin Tran
07/23/2021, 7:21 AMjulioromano
07/23/2021, 7:22 AMTin Tran
07/23/2021, 7:33 AMHiltViewModel
. Shouldn’t its lifecycle be managed by compose navigation as well?composable(
Screens.Login.route,
deepLinks = listOf(navDeepLink {
uriPattern = Screens.Login.pattern
})
) {
Login(
viewModel = hiltViewModel(),
navController = navController,
modifier = Modifier
.fillMaxSize()
)
}
julioromano
07/23/2021, 8:43 AMhiltViewModel()
too, I reverted to viewModel()
only for the bug report.
You might wanna try to create a dummy viewmodel and get it with viewModel()
to check if the issue is specific to hiltViewModel().
Login
composable is being called multiple times, which in turns calls hiltViewModel()
multiple times.
If you’re seeing multiple calls to the viewModel’s init
it might mean that the owner’s lifecycle has already been torn down therefore hiltViewModel()
creates a new instance of the viewModel instead of returning the last cached one.hiltViewModel()
inside the Login
composable. I know this will impact testability coz you can’t pass in another viewModel during tests, but perhaps it can be helpful to debug the issue and then file a bug report.Tin Tran
07/23/2021, 8:46 AM@Composable
fun Login(viewModel: LoginViewModel) {
val state by viewModel.dataState.collectAsState()
// layout code
when (state) {
is DataState.LOADING -> {
Loading(
modifier = Modifier
.fillMaxSize()
.background(color = LoadingBlack)
)
}
is DataState.SUCCESS<*> -> {
Log.i("LOGIN", "Login success")
navController.navigate(Screens.Home.route) {
popUpTo(Screens.Login.route) {
inclusive = true
}
}
}
else -> {
viewModel.reduce(LoginEvent.IDLE)
}
}
}
julioromano
07/23/2021, 8:48 AMnavigate
call should be put inside a LaunchedEffect or similar.Tin Tran
07/23/2021, 8:49 AMjulioromano
07/23/2021, 8:50 AMTin Tran
07/23/2021, 8:52 AMjulioromano
07/23/2021, 8:52 AMis DataState.SUCCESS<*> -> {
LaunchedEffect(state) {
Log.i("LOGIN", "Login success")
navController.navigate(Screens.Home.route) {
popUpTo(Screens.Login.route) {
inclusive = true
}
}
}
}
Is it anti pattern if I pass the nav controller to the viewmodel and let it navigate instead?It may break the lifetime scope of objects: The Lifetime of a view model is wider than that of the navController obj (which is tied to the fragment or activity lifetime). If you do that and your activity/fragment is recreated during a configuration change, the viewmodel wont’ be recreated and might keep using an old instance of navController while the newly instantiated activity/fragment will have a newer one.
Tin Tran
07/23/2021, 8:56 AM