Using Dagger Hilt In Android Applications

How to use dagger-hilt to improve your workflow when working on Android applications

I'll be assuming the reader has a solid grasp of the basic knowledge of kotlin, dagger and dagger-android.

The Current Situation With Dependency Injection

If you've been around long enough in android development, you've probably used tools like dagger and dagger-android to handle dependency injection in your applications. I'm pretty sure we are all too familiar with the amount of code we have to write to setup our dependencies. You've probably had to create an ApplicationComponent Interface, multiple dagger modules for your activities/fragments and yet you still needed to wire up factories so you can inject your view models. Apparently that is also not the last of your troubles, you also have to repeat all of this processes again in order to get any meaningful integration testing done. Clearly the dagger-android library can be begin to feel like a burden.

Why Use Hilt?

The dagger-hilt library addresses virtually all the problems listed in the above section. The following are some of the benefits of using hilt:

  • Reduced boilerplate
  • Decoupled build dependencies
  • Simplified configuration
  • Improved testing
  • Standardized components

Want to know more about the benefits of Hilt, checkout Why Hilt on Dagger Dev

Talk Is Cheap, Show Me The Code


To use Hilt, add the following build dependencies to the Android Gradle module’s build.gradle file:

apply plugin: 'dagger.hilt.android.plugin'

dependencies {
  implementation 'com.google.dagger:hilt-android:<VERSION>'
  kapt 'com.google.dagger:hilt-android-compiler:<VERSION>'

  // For instrumentation tests
  androidTestImplementation  'com.google.dagger:hilt-android-testing:2.28-alpha'
  kaptAndroidTest 'com.google.dagger:hilt-android-compiler:2.28-alpha'

  // For local unit tests
  testImplementation 'com.google.dagger:hilt-android-testing:2.28-alpha'
  kaptTest 'com.google.dagger:hilt-android-compiler:2.28-alpha'
}

kapt {
 correctErrorTypes true
}

Add the following to your project's build.gradle

buildscript {
  repositories {
    // other repositories...
    mavenCentral()
  }
  dependencies {
    // other plugins...
    classpath 'com.google.dagger:hilt-android-gradle-plugin:<version>'
  }
}

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

@HiltAndroidApp
public final class MyApplication extends Application {}

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

@AndroidEntryPoint
public final class MainActivity extends MyBaseActivity {
  @Inject Foo foo; // Bindings in SingletonComponent or ActivityComponent

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

    // Do something with foo ...
  }
}

Using Hilt With ViewModels

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

Add the following to app/build.gradle

dependencies {
  ...
  implementation 'androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha01'
  kapt 'androidx.hilt:hilt-compiler:1.0.0-alpha01'
}

Provide a ViewModel using the @ViewModelInject annotation in the ViewModel object's constructor. You must also annotate the SavedStateHandle dependency with @Assisted:

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

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

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

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.

@Module
@InstallIn(SingletonComponent.class) // Installs FooModule in the generate SingletonComponent.
public final class FooModule {
  @Provides
  static Foo provideFoo() {...}
}

Hurray!!! You are ready to start using hilt in your android application. Personally, I felt the implementation of Hilt is easy when compared to dagger. If you feel the same after testing the above, please give it a try in your next project.

Looking for a new challenge? Join Our Team

Like 4 likes
Anu Karounwi
Android engineer at oozou
Share:

Join the conversation

This will be shown public
All comments are moderated

Get our stories delivered

From us to your inbox weekly.