Usar o Hilt com outras bibliotecas do Jetpack

O Hilt inclui extensões para fornecer classes de outras bibliotecas do Jetpack. Atualmente, o Hilt oferece suporte aos seguintes componentes do Jetpack:

  • Escrever
  • ViewModel
  • Navegação
  • WorkManager

É preciso adicionar as dependências do Hilt para aproveitar essas integrações. Para ver mais informações sobre como adicionar dependências, consulte Injeção de dependências com o Hilt.

Integração com o Jetpack Compose

Para ver como o Hilt se integra ao Jetpack Compose, consulte a seção Compose e outras bibliotecas.

Injetar objetos ViewModel com Hilt

Forneça um ViewModel anotando com @HiltViewModel e usando a anotação @Inject no construtor do objeto ViewModel.

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

Em seguida, uma atividade anotada com @AndroidEntryPoint pode receber a instância ViewModel normalmente usando ViewModelProvider ou as by viewModels() extensões KTX:

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

Usar a injeção assistida com ViewModels

O Hilt oferece suporte à injeção assistida para ViewModels. A injeção assistida permite injetar argumentos dinâmicos de execução junto com dependências gerenciadas pelo Hilt. Para usar a injeção assistida, anote o construtor do ViewModel com @AssistedInject, e marque os parâmetros dinâmicos com @Assisted. Você também precisa definir uma interface @AssistedFactory, que atua como uma ponte para o Hilt gerar automaticamente o @ViewModelProvider.Factory necessário.

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

No Compose, é possível usar a fábrica assistida transmitindo-a para a função hiltViewModel durante a navegação ou inicialização da tela. Essa abordagem elimina a necessidade de um boilerplate de fábrica manual, mantendo o ViewModel com o escopo correto para a backstack de navegação. Para mais informações, consulte a documentação do Hilt sobre injeção assistida.

@ViewModelScoped

Todos os ViewModels do Hilt são fornecidos pelo ViewModelComponent, que segue o mesmo ciclo de vida de um ViewModel. Por isso, ele pode sobreviver às mudanças de configuração. Para definir o escopo de uma dependência para um ViewModel, use a anotação @ViewModelScoped.

Um tipo @ViewModelScoped vai fazer com que uma única instância do tipo com escopo seja fornecida em todas as dependências injetadas no ViewModel. Outras instâncias de um ViewModel que solicitam a instância com escopo vão receber uma instância diferente.

Se uma única instância tiver que ser compartilhada entre vários ViewModels, ela vai precisar ter o escopo definido usando @ActivityRetainedScoped ou @Singleton.

Integração com as bibliotecas de navegação do Jetpack

Adicione estas outras dependências ao arquivo do 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'
}

No Jetpack Compose, as bibliotecas Navigation Compose e Navigation 3 usam a função hiltViewModel para recuperar automaticamente um ViewModel com escopo para o destino de navegação atual.

No Navigation 3, os destinos de navegação são representados por NavEntrys. Defina o escopo dos ViewModels para NavEntrys usando rememberViewModelStoreNavEntryDecorator. Use hiltViewModel no provedor para que NavEntry recupere o ViewModel associado.

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

No Navigation Compose, os ViewModels são definidos automaticamente para destinos de navegação. Para mais informações, consulte Hilt e navegação.

val viewModel = hiltViewModel()

Injetar WorkManager com o Hilt

Adicione as seguintes dependências a mais ao arquivo do Gradle. Além da biblioteca, você precisa incluir outro processador de anotações que funcione sobre o processador Hilt:

app/build.gradle

Kotlin

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

Groovy

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

Injete um Worker usando a @HiltWorker anotação na classe e @AssistedInject no Worker construtor do objeto. Só é possível usar @Singleton ou vinculações sem escopo em objetos Worker. Também é necessário anotar as dependências Context e WorkerParameters com @Assisted:

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

Em seguida, faça com que a classe Application implemente a interface Configuration.Provider, injete uma instância de HiltWorkFactory e a transmita para a configuração WorkManager, da seguinte maneira:

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

  @Inject lateinit var workerFactory: HiltWorkerFactory

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