When I want to share a view model between various views I would use by viewmodels
. I recently began looking into hilt and was wondering if hiltviewmodel
would accomplish the same thing? That is to allow me to share a single(same instance) of a viewmodel?

- 2,595
- 9
- 43
- 70
2 Answers
by viewModels():
- property delegate.
- the first time create, next time return the same instance(in the same scope, the scope is the same activity)
= hiltViewModel():
- only used in @Composable annotated function.
- the first time create, next time return the same instance(in the same scope, the scope is NavGraph, if no graph, fragment/activity)
you 'd best build a demo and practise it, and log the instance to see if the same instance.
val viewModel: ViewModelA by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
HiltDemoTheme {
val viewModel2: ViewModelA = hiltViewModel()
val viewModel3: ViewModelA = viewModel()
val viewModel4: ViewModelA by viewModels()
Log.d("Jeck", "$viewModel")
Log.d("Jeck", "$viewModel2")
Log.d("Jeck", "$viewModel3")
Log.d("Jeck", "$viewModel4")// the four get the same instance
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colors.background
) {
}
}
}
Documentation: Hilt and Navigation
When using Navigation Compose, always use the hiltViewModel composable function to obtain an instance of your @HiltViewModel annotated ViewModel. This works with fragments or activities that are annotated with @AndroidEntryPoint.
-
When to use `hiltViewModel`? – IgorGanapolsky May 09 '23 at 16:16
The ViewModel annotated with @HiltViewModel
will be available for creation by the HiltViewModelFactory
and can be retrieved by default in an Activity or Fragment annotated with @AndroidEntryPoint
by using ViewModelProvider
or the by viewModels()
.
Also, by viewModels
returns a property delegate to access ViewModel by default scoped to the fragment. Remember viewModels
is not only used with Hilt, but it can be used to provide simple ViewModel instances as well when not using Hilt.
On the other hand, @HiltViewModel
, tells Hilt that this ViewModel can be injected into other classes marked with @AndroidEntryPoint
as well as allowing Hilt to inject other dependencies into this ViewModel.
All Hilt ViewModels are provided by the ViewModelComponent which follows the same lifecycle as a ViewModel, and as such, can survive configuration changes. To scope a dependency to a ViewModel use the @ViewModelScoped annotation.
A @ViewModelScoped type will make it so that a single instance of the scoped type is provided across all dependencies injected into the ViewModel. Other instances of a ViewModel that request the scoped instance will receive a different instance.
If a single instance needs to be shared across various ViewModels, then it should be scoped using either @ActivityRetainedScoped or @Singleton.
[Source: https://developer.android.com/training/dependency-injection/hilt-jetpack#viewmodelscoped]
And if the shared/single ViewModel is among different fragments, you could bind the lifecycle of the injected ViewModel to the parent Activity by by activityViewModels
.
More information:
https://dagger.dev/api/latest/dagger/hilt/android/lifecycle/HiltViewModel.html &
https://dagger.dev/hilt/view-model.html &
https://developer.android.com/training/dependency-injection/hilt-jetpack

- 3,341
- 6
- 53
- 91