Utiliser Hilt avec d'autres bibliothèques Jetpack

Hilt comprend des extensions permettant de fournir des classes issues d'autres bibliothèques Jetpack. Actuellement, Hilt prend en charge les composants Jetpack suivants :

  • Nouveau message
  • ViewModel
  • Navigation
  • WorkManager

Vous devez ajouter les dépendances de Hilt pour bénéficier de ces intégrations. Pour en savoir plus sur l'ajout de dépendances, consultez la section Injection de dépendances avec Hilt.

Intégration à Jetpack Compose

Pour découvrir l'intégration de Hilt à Jetpack Compose, consultez la section sur Hilt de Compose et autres bibliothèques.

Injecter des objets ViewModel avec Hilt

Fournissez un ViewModel en l'annotant avec @HiltViewModel et en utilisant l'annotation @Inject dans le constructeur de l'objet ViewModel.

@HiltViewModel
class ExampleViewModel @Inject constructor(
  private val savedStateHandle: SavedStateHandle,
  private val repository: ExampleRepository
) : ViewModel() {
  ...
}

Ensuite, une activité annotée avec @AndroidEntryPoint peut obtenir l'instance ViewModel comme d'habitude en utilisant ViewModelProvider ou les extensions KTX de by viewModels() :

@AndroidEntryPoint
class ExampleActivity : AppCompatActivity() {
  private val exampleViewModel: ExampleViewModel by viewModels()
  ...
}

Utiliser l'injection assistée avec les ViewModels

Hilt est compatible avec l'injection assistée pour les ViewModels. L'injection assistée vous permet d'injecter des arguments d'exécution dynamiques en plus des dépendances gérées par Hilt. Pour utiliser l'injection assistée, annotez le constructeur de votre ViewModel avec @AssistedInject et marquez les paramètres dynamiques avec @Assisted. Vous devez également définir une interface @AssistedFactory, qui sert de pont pour que Hilt génère automatiquement les @ViewModelProvider.Factory nécessaires.

@HiltViewModel(assistedFactory = MyViewModel.Factory::class)
class MyViewModel @AssistedInject constructor(
    @Assisted val userId: String,
    private val repository: MyRepository
) : ViewModel() {
    @AssistedFactory interface Factory {
        fun create(userId: String): MyViewModel
    }
}

Dans Compose, vous pouvez utiliser la fabrique assistée en la transmettant à la fonction hiltViewModel lors de l'initialisation de la navigation ou de l'écran. Cette approche élimine le besoin de boilerplate de configuration de fabrique manuelle tout en gardant votre ViewModel correctement limité à la pile « Retour » de navigation. Pour en savoir plus, consultez la documentation Hilt sur l'injection assistée.

"@ViewModelScoped"

Tous les ViewModels de Hilt sont fournis par le ViewModelComponent, qui suit le même cycle de vie qu'un ViewModel. Par conséquent, ils peuvent survivre aux changements de configuration. Pour définir le champ d'application d'une dépendance sur un ViewModel, utilisez l'annotation @ViewModelScoped.

Avec le type @ViewModelScoped, une seule instance du type limité est fournie pour toutes les dépendances injectées dans le ViewModel. Les autres instances d'un ViewModel qui demandent l'instance limitée recevront une autre instance.

Si une seule instance doit être partagée entre différents ViewModels, son champ d'application doit être défini à l'aide de @ActivityRetainedScoped ou de @Singleton.

Intégration aux bibliothèques de navigation Jetpack

Ajoutez les dépendances supplémentaires suivantes à votre fichier Gradle :

app/build.gradle

Kotlin

dependencies {
    ...
    implementation("androidx.hilt:hilt-lifecycle-viewmodel-compose:1.3.0")
}

Groovy

dependencies {
    ...
    implementation 'androidx.hilt:hilt-lifecycle-viewmodel-compose:1.3.0'
}

Dans Jetpack Compose, les bibliothèques Navigation Compose et Navigation 3 utilisent toutes deux la fonction hiltViewModel pour récupérer automatiquement un ViewModel limité à la destination de navigation actuelle.

Dans Navigation 3, les destinations de navigation sont représentées par des NavEntry. Définissez le champ d'application des ViewModels sur les NavEntry à l'aide de rememberViewModelStoreNavEntryDecorator. Utilisez hiltViewModel à l'intérieur du fournisseur pour ce NavEntry afin de récupérer le ViewModel associé.

NavDisplay(...,
  entryDecorators = listOf(..., rememberViewModelStoreNavEntryDecorator()),
  entryProvider = entryProvider {
    entry { key ->
      val viewModel = hiltViewModel()
      MyScreen(viewModel = viewModel)
    }
  }
)

Dans Navigation Compose, les ViewModels sont automatiquement limités aux destinations de navigation. Pour en savoir plus, consultez Hilt et Navigation.

val viewModel = hiltViewModel()

Injecter WorkManager avec Hilt

Ajoutez les dépendances supplémentaires suivantes à votre fichier Gradle. Notez qu'en plus de la bibliothèque, vous devez inclure un processeur d'annotations supplémentaire qui fonctionne avec le processeur d'annotations Hilt :

app/build.gradle

Kotlin

dependencies {
    implementation("androidx.hilt:hilt-work:1.0.0")
    // When using Kotlin.
    ksp("androidx.hilt:hilt-compiler:1.4.0")
}

Groovy

dependencies {
  ...
  implementation 'androidx.hilt:hilt-work:1.0.0'
  // When using Kotlin.
  ksp 'androidx.hilt:hilt-compiler:1.4.0'
}

Injectez un Worker à l'aide de l'annotation @HiltWorker dans la classe et de @AssistedInject dans le constructeur de l'objet Worker. Vous pouvez utiliser uniquement @Singleton ou des liaisons sans champ d'application dans les objets Worker. Vous devez également annoter les dépendances Context et WorkerParameters avec @Assisted :

@HiltWorker
class ExampleWorker @AssistedInject constructor(
  @Assisted appContext: Context,
  @Assisted workerParams: WorkerParameters,
  workerDependency: WorkerDependency
) : Worker(appContext, workerParams) { ... }

Ensuite, faites en sorte que votre classe Application implémente l'interface Configuration.Provider, injecte une instance de HiltWorkFactory et la transmette dans la configuration WorkManager, comme suit :

@HiltAndroidApp
class ExampleApplication : Application(), Configuration.Provider {

  @Inject lateinit var workerFactory: HiltWorkerFactory

  override fun getWorkManagerConfiguration() =
      Configuration.Builder()
            .setWorkerFactory(workerFactory)
            .build()
}