Android 12 Developer Preview is here! Try it out, and give us your feedback!

Hilt and Jetpack integrations

Hilt includes extensions for providing classes from other Jetpack libraries. Hilt currently supports the following Jetpack components:

  • ViewModel
  • WorkManager

You must add the Hilt dependencies to take advantage of these integrations. For more information about adding dependencies, see Dependency injection with 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.

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;
  }
  ...
}

Then, an activity or a fragment that is annotated with @AndroidEntryPoint can get the ViewModel instance as normal using ViewModelProvider or the by viewModels() KTX extensions:

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

All Hilt ViewModels are provided by the ViewModelComponent which follows the same lifecycle as a ViewModel, and as such, can survive configuration changes. To scope a dependency to a ViewModel use the @ViewModelScoped annotation.

A @ViewModelScoped type will make it so that a single instance of the scoped type is provided across all dependencies injected into the ViewModel. Other instances of a ViewModel that request the scoped instance will receive a different instance.

If a single instance needs to be shared across various ViewModels, then it should be scoped using either @ActivityRetainedScoped or @Singleton.

Integration with the Jetpack navigation library

Add the following additional dependencies to your Gradle file:

app/build.gradle

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

If your ViewModel is scoped to the navigation graph, use the hiltNavGraphViewModels function that works with fragments that are annotated with @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)

Inject WorkManager with Hilt

Add the following additional dependencies to your Gradle file. Note that in addition to the library, you need to include an additional annotation processor that works on top of the Hilt annotation processor:

app/build.gradle

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

Inject a Worker using the @HiltWorker annotation in the class and @AssistedInject in the Worker object's constructor. You can use only @Singleton or unscoped bindings in Worker objects. You must also annotate the Context and WorkerParameters dependencies with @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;
  }
  ...
}

Then, have your Application class implement the Configuration.Provider interface, inject an instance of HiltWorkFactory, and pass it into the WorkManager configuration as follows:

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 Configuration.Builder()
             .setWorkerFactory(workerFactory)
             .build();
  }
}