Dependency injection on Android with Hilt
Learn about Jetpack’s recommended library for dependency injection
Dependency injection (DI) is a technique widely used in programming and well suited to Android development, where dependencies are provided to a class instead of creating them itself. By following DI principles, you lay the groundwork for good app architecture, greater code reusability, and ease of testing. Have you ever tried manual dependency injection in your app? Even with many of the existing dependency injection libraries today, it requires a lot of boilerplate code as your project becomes larger, since you have to construct every class and its dependencies by hand, and create containers to reuse and manage dependencies.
By following DI principles, you lay the groundwork for good app architecture, greater code reusability, and ease of testing.
The new Hilt library defines a standard way to do DI in your application by providing containers for every Android class in your project and managing their lifecycles automatically for you. Hilt is currently in alpha, try it in your app and give us feedback using this link.
Hilt is built on top of the popular DI library Dagger so benefits from the compile time correctness, runtime performance, scalability, and Android Studio support that Dagger provides. Due to this, Dagger’s seen great adoption on 30% of top 10k apps of the Google Play Store. However, because of the compile time code generation, expect a build time increase.
Since many Android framework classes are instantiated by the OS itself, there’s an associated boilerplate when using Dagger in Android apps. Unlike Dagger, Hilt is integrated with Jetpack libraries and Android framework classes and removes most of that boilerplate to let you focus on just the important parts of defining and injecting bindings without worrying about managing all of the Dagger setup and wiring. It automatically generates and provides:
-
Components for integrating Android framework classes with Dagger that you would otherwise need to create by hand.
-
Scope annotations for the components that Hilt generates automatically.
-
Predefined bindings and qualifiers.
Best of all, as Dagger and Hilt can coexist together, apps can be migrated on an as-needed basis.
Hilt in action
Just to show you how easy to use Hilt is, let’s perform some quick DI in a typical Android app. Let’s make Hilt inject an AnalyticsAdapter
into our MainActivity
.
First, enable Hilt in your app by annotating your application class with the @HiltAndroidApp
to trigger Hilt’s code generation:
@HiltAndroidApp
class MyApplication : Application() {/* ... */}
Second, tell Hilt how to provide instances of AnalyticsAdapter
by annotating its constructor with @Inject
:
class AnalyticsAdapter @Inject constructor() {/* ... */}
And third, to inject an instance of AnalyticsAdapter
into MainActivity
, enable Hilt in the activity with the @AndroidEntryPoint
annotation and perform field injection using the @Inject
annotation:
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
@Inject lateinit var analytics: AnalyticsAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// analytics instance has been populated by Hilt
// and it's ready to be used
}
}
For more information, you can easily check out what the new annotations do in the cheat sheet section below.
Comes with Jetpack support!
You can use your favourite Jetpack libraries with Hilt out of the box. We’re providing direct injection support for ViewModel and WorkManager in this release.
For example, to inject a Architecture Components ViewModel LoginViewModel
into a LoginActivity
: annotate LoginViewModel
with @ViewModelInject
and use it in the activity or fragment as you’d expect:
class LoginViewModel @ViewModelInject constructor(
private val analyticsAdapter: AnalyticsAdapter
): ViewModel() { ... }
@AndroidEntryPoint
class LoginActivity : AppCompatActivity() {
private val loginViewModel: LoginViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// loginViewModel is ready to be used
}
}
Learn more about Jetpack support in the docs.
Start using Hilt
If you’re intrigued by Hilt and want to learn more about it, here’s some resources for you to learn in the way you prefer:
Getting started with Hilt
Learn how to add Hilt in your Android app with this guide.
Documentation
If you’re new to DI or Dagger, check out our guide to add Hilt to an Android app. Alternatively, if you already know Dagger, we’re also providing documentation on dagger.dev.
If you’re just curious about the new annotations and what you can do with Hilt, check out this cheat sheet in the section below.
For Dagger users
If you’re already using Dagger or dagger.android in your app, check out this migration guide or the codelab mentioned below to help you switch to Hilt. As Dagger and Hilt can coexist together, you can migrate your app incrementally.
Codelabs
To learn Hilt in a step-by-step approach, we just released two codelabs:
Sample code
Do you want to see how Hilt is used in existing apps? Go check its usage in the Google I/O 2020 app and in the dev-hilt
branch of the Android architecture-samples Github repository.
Feedback
Hilt is currently in alpha, try it in your app and give us feedback using this link.
Cheat sheet
This cheat sheet allows you to quickly see what the different Hilt and Dagger annotations do and how to use them.
Hilt and Dagger annotations cheat sheet. Download in PDF here.