diff --git a/hilt/view-model.md b/hilt/view-model.md index abdce959a7b..083877a3277 100644 --- a/hilt/view-model.md +++ b/hilt/view-model.md @@ -168,3 +168,133 @@ class MovieViewModel @Inject constructor( } ``` {: .c-codeselector__code .c-codeselector__code_kotlin } + +## Assisted Injection + +Hilt View Models can also be +[assisted injected](https://dagger.dev/dev-guide/assisted-injection). Compared +to using `SavedStateHandle`, this enables passing data that are not `Parcelable` +to a Hilt View Model easily. To use asssited injection, annotate the view model +constructor with `@AssistedInject` and the assisted parameters with `@Assisted`, +and specify the assisted factory in the `@HiltViewModel` annotation: + +
+ + + +```java +@HiltViewModel(assistedFactory = MovieViewModelFactory.class) +class MovieViewModel { + @AssistedInject MovieViewModel(@Assisted int movieId) { + // ... + } +} +``` +{: .c-codeselector__code .c-codeselector__code_java } + +```kotlin +@HiltViewModel(assistedFactory = MovieViewModelFactory::class) +class MovieViewModel @AssistedInject constructor( + @Assisted val movieId: Int +) : ViewModel { + // ... +} +``` +{: .c-codeselector__code .c-codeselector__code_kotlin } + +**Note:** Unlike `SavedStateHandle`, the values passed through assisted +parameters to a Hilt View Model do not get saved to disk. They have the same +scope as the view model and do not persist after the lifecycle of the view model +has ended, e.g. containing activity gets popped off the stack or process death. +Consider using normal injection with `SavedStateHandle` instead or other +mechanisms if persistence is needed. +{: .c-callouts__note} + +Next, define the assisted factory with an abstract factory method that returns +the view model: + + + + + +```java +@AssistedFactory +interface MovieViewModelFactory { + MovieViewModel create(int movieId); +} +``` +{: .c-codeselector__code .c-codeselector__code_java } + +```kotlin +@AssistedFactory +interface MovieViewModelFactory { + fun create(val movieId: Int): MovieViewModel +} +``` +{: .c-codeselector__code .c-codeselector__code_kotlin } + +**Note:** It is an error to request the assisted factory for view models from +Dagger directly since the factory may be used to create view model instances +that are not stored correctly. This is checked at compile time by Hilt. +{:.c-callouts__note} + +Finally, pass a callback to the helper function +`HiltViewModelExtensions.withCreationCallback()` to create a `CreationExtras` +that can be used with the `ViewModelProvider` API or other view model functions +like `by viewModels()`. Use the passed in factory to create a view model +instance inside the callback: + + + + + +```java +@AndroidEntryPoint +public final class MyActivity extends AppCompatActivity { + + private int movieId = 1; + private MovieViewModel movieViewModel; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + movieViewModel = new ViewModelProvider( + getViewModelStore(), + getDefaultViewModelProviderFactory(), + HiltViewModelExtensions.withCreationCallback( + getDefaultViewModelCreationExtras(), + (MyViewModel.Factory factory) -> factory.create(movieId))) + .get(MyInjectedViewModel.class); + } +} +``` +{: .c-codeselector__code .c-codeselector__code_java } + +```kotlin +@AndroidEntryPoint +class MyActivity : AppCompatActivity() { + private val movieId = 1 + private val movieViewModel by viewModels