Quick Start Guide

Introduction

Hilt makes it easy to add dependency injection to your Android app. This tutorial will guide you through bootstrapping an existing app to use Hilt.

For more on the basic concepts of Hilt’s components, check out Hilt Components.

Gradle vs non-Gradle users

For Gradle users, the Hilt Gradle plugin makes usages of some Hilt annotations easier by avoiding references to Hilt generated classes.

Without the Gradle plugin, the base class must be specified in the annotation and the annotated class must extend the generated class:

Java
Kotlin
@HiltAndroidApp(MultiDexApplication.class)
public final class MyApplication extends Hilt_MyApplication {}
@HiltAndroidApp(MultiDexApplication::class)
class MyApplication : Hilt_MyApplication()

With the Gradle plugin the annotated class can extend the base class directly:

Java
Kotlin
@HiltAndroidApp
public final class MyApplication extends MultiDexApplication {}
@HiltAndroidApp
class MyApplication : MultiDexApplication()

Further examples assume usage of the Hilt Gradle plugin.

Hilt Application

All apps using Hilt must contain an Application class annotated with @HiltAndroidApp. @HiltAndroidApp kicks off the code generation of the Hilt components and also generates a base class for your application that uses those generated components. Because the code generation needs access to all of your modules, the target that compiles your Application class also needs to have all of your Dagger modules in its transitive dependencies.

Just like other Hilt Android entry points, Applications are members injected as well. This means you can use injected fields in the Application after super.onCreate() has been called.

For example, take the class called MyApplication that extends MyBaseApplication and has a member variable Bar:

Java
Kotlin
public final class MyApplication extends MyBaseApplication {
  @Inject Bar bar;

  @Override public void onCreate() {
    super.onCreate();

    MyComponent myComponent =
        DaggerMyComponent
            .builder()
            ...
            .build();

    myComponent.inject(this);
  }
}
class MyApplication : MyBaseApplication() {
  @Inject lateinit var bar: Bar

  override fun onCreate() {
    super.onCreate()

    val myComponent =
        DaggerMyComponent
            .builder()
            ...
            .build()

    myComponent.inject(this)
  }
}

With Hilt’s members injection, the above code becomes:

Java
Kotlin
@HiltAndroidApp
public final class MyApplication extends MyBaseApplication {
  @Inject Bar bar;

  @Override public void onCreate() {
    super.onCreate(); // Injection happens in super.onCreate()
    // Use bar
  }
}
@HiltAndroidApp
class MyApplication : MyBaseApplication() {
  @Inject lateinit var bar: Bar

  override fun onCreate() {
    super.onCreate() // Injection happens in super.onCreate()
    // Use bar
  }
}

For more details, see Hilt Application.

@AndroidEntryPoint

Once you have enabled members injection in your Application, you can start enabling members injection in your other Android classes using the @AndroidEntryPoint annotation. You can use @AndroidEntryPoint on the following types:

  1. Activity
  2. Fragment
  3. View
  4. Service
  5. BroadcastReceiver

ViewModels are not directly supported, but are instead supported by a Jetpack extension. The following example shows how to add the annotation to an activity, but the process is the same for other types.

To enable members injection in your activity, annotate your class with @AndroidEntryPoint.

Java
Kotlin
@AndroidEntryPoint
public final class MyActivity extends MyBaseActivity {
  @Inject Bar bar; // Bindings in ApplicationComponent or ActivityComponent

  @Override
  public void onCreate() {
    // Injection happens in super.onCreate().
    super.onCreate();

    // Do something with bar ...
  }
}
@AndroidEntryPoint
class MyActivity : MyBaseActivity() {
  @Inject lateinit var bar: Bar // Bindings in ApplicationComponent or ActivityComponent

  override fun onCreate() {
    // Injection happens in super.onCreate().
    super.onCreate()

    // Do something with bar ...
  }
}

Note: Hilt currently only supports activities that extend ComponentActivity and fragments that extend androidx library Fragment, not the (now deprecated) Fragment in the Android platform.

For more details, see @AndroidEntryPoint.

Hilt Modules

Hilt modules are standard Dagger modules that have an additional @InstallIn annotation that determines which Hilt component(s) to install the module into.

When the Hilt components are generated, the modules annotated with @InstallIn will be installed into the corresponding component or subcomponent via @Component#modules or @Subcomponent#modules respectively. Just like in Dagger, installing a module into a component allows that binding to be accessed as a dependency of other bindings in that component or any child component(s) below it in the component hierarchy. They can also be accessed from the corresponding @AndroidEntryPoint classes. Being installed in a component also allows that binding to be scoped to that component.

Using @InstallIn

A module is installed in a Hilt Component by annotating the module with the @InstallIn annotation. These annotations are required on all Dagger modules when using Hilt, but this check may be optionally disabled.

Note: If a module does not have an @InstallIn annotation, the module will not be part of the component and may result in compilation errors.

Specify which Hilt Component to install the module in by passing in the appropriate Component type(s) to the @InstallIn annotation. For example, to install a module so that anything in the application can use it, use ApplicationComponent:

Java
Kotlin
@Module
@InstallIn(ApplicationComponent.class) // Installs FooModule in the generate ApplicationComponent.
public final class FooModule {
  @Provides
  static Bar provideBar() {...}
}
@Module
@InstallIn(ApplicationComponent::class) // Installs FooModule in the generate ApplicationComponent.
object FooModule {
  @Provides
  fun provideBar(): Bar {...}
}

For more details, see Hilt Modules.