I have found a similar question here. At the time of writing this question there is only this answer avaliable, which does not provide any help to me, and I believe also to the person who asked the question.
I checked the repo which is linked in the answer and it "solves" the problem by creating an init method in the viewmodel and calling it in the Activity/Fragment.
Since the viewmodel has already been injected, this solution does not seem like ideal to me, and I would like to know if there are other options available when using hilt.
Inject ViewModel objects with Hilt Provide a ViewModel by annotating it with @HiltViewModel and using the @Inject annotation in the ViewModel object's constructor. Note: To use Dagger's assisted injection with ViewModels, see the following Github issue.
The koin-android Gradle module introduces a new viewModel DSL keyword that comes in complement of single and factory , to help declare a ViewModel component and bind it to an Android Component lifecycle. Your declared component must at least extends the android.
The viewModels() extension function is provided by androidx KTX . Even if the ViewModel has savedStateHandle or is taking the intent bundle from the Activity, it doesn't need to be explicitly injected in. The viewModels() extension function does all that automatically behind the scene.
Assisted injection is a dependency injection (DI) pattern that is used to construct an object where some parameters may be provided by the DI framework and others must be passed in at creation time (a.k.a “assisted”) by the user.
As per this comment and the release of AndroidX Hilt 1.0.0-alpha03, Hilt has supported ViewModels that take a SavedStateHandle
as a parameter (right alongside your other injected parameters).
This SavedStateHandle
is automatically, without you doing anything, populated with the arguments passed to your fragment (i.e., the same arguments you get from requireArguments()
and the same arguments that are read by Safe Args).
Therefore in your ViewModel's constructor, you can immediately access those arguments from the SavedStateHandle
, without having to do any manual passing of arguments to your ViewModel.
@HiltViewModel
class MainViewModel @Inject constructor(
val userDataManager: UserDataManager,
savedStateHandle: SavedStateHandle
) : ViewModel() {
init {
// Use the same argName as in your navigation graph
val yourArgument: String = savedStateHandle["argName"]
// Now use that argument to load your data, etc.
}
}
The feature request for Safe Args integration with SavedStateHandle is already fixed and will be part of the upcoming Navigation 2.4.0-alpha01
release. Once that is released, you'd be able to do something like MainFragmentArgs.fromSavedStateHandle(savedStateHandle)
to get the same Args
class you're currently able to get from by navArgs()
within your ViewModel.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With