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 :

  • ViewModel
  • Navigation
  • Compose
  • 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.

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.

Kotlin

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

Java

@HiltViewModel
public class ExampleViewModel extends ViewModel {

  private final ExampleRepository repository;
  private final SavedStateHandle savedStateHandle;

  @Inject
  ExampleViewModel(
      SavedStateHandle savedStateHandle,
      ExampleRepository repository)
    {
    this.savedStateHandle = savedStateHandle;
    this.repository = repository;
  }
  ...
}

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

Kotlin

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

Java

@AndroidEntryPoint
public class ExampleActivity extends AppCompatActivity {

  private ExampleViewModel exampleViewModel;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    exampleViewModel = new ViewModelProvider(this).get(ExampleViewModel.class);
  }
  ...
}

"@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 à la bibliothèque de navigation Jetpack

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

app/build.gradle

Groovy

dependencies {
    ...
    implementation 'androidx.hilt:hilt-navigation-fragment:1.0.0'
}

Kotlin

dependencies {
    ...
    implementation("androidx.hilt:hilt-navigation-fragment:1.0.0")
}

Si le champ d'application de votre ViewModel est défini sur le graphique de navigation, utilisez la fonction hiltNavGraphViewModels qui fonctionne avec les fragments annotés avec @AndroidEntryPoint.

Kotlin

val viewModel: ExampleViewModel by hiltNavGraphViewModels(R.id.my_graph)

Java

NavBackStackEntry backStackEntry = navController.getBackStackEntry(R.id.my_graph);

ExampleViewModel exampleViewModel = new ViewModelProvider(
  backStackEntry,
  HiltViewModelFactory.create(context, backStackEntry)
).get(ExampleViewModel.class)

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 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

Groovy

dependencies {
  ...
  implementation 'androidx.hilt:hilt-work:1.0.0'
  // When using Kotlin.
  kapt 'androidx.hilt:hilt-compiler:1.0.0'
  // When using Java.
  annotationProcessor 'androidx.hilt:hilt-compiler:1.0.0'
}

Kotlin

dependencies {
    implementation("androidx.hilt:hilt-work:1.0.0")
    // When using Kotlin.
    kapt("androidx.hilt:hilt-compiler:1.0.0")
    // When using Java.
    annotationProcessor("androidx.hilt:hilt-compiler:1.0.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 :

Kotlin

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

Java

@HiltWorker
public class ExampleWorker extends Worker {

  private final WorkerDependency workerDependency;

  @AssistedInject
  ExampleWorker(
    @Assisted @NonNull Context context,
    @Assisted @NonNull WorkerParameters params,
    WorkerDependency workerDependency
  ) {
    super(context, params);
    this.workerDependency = workerDependency;
  }
  ...
}

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 :

Kotlin

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

  @Inject lateinit var workerFactory: HiltWorkerFactory

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

Java

@HiltAndroidApp
public class ExampleApplication extends Application implements Configuration.Provider {

  @Inject HiltWorkerFactory workerFactory;

  @Override
  public Configuration getWorkManagerConfiguration() {
    return new Configuration.Builder()
             .setWorkerFactory(workerFactory)
             .build();
  }
}