tutorial, hilt_hierarchy, librariesandroid,

Librariesandroid - hilt_hierarchy

Upendra Upendra Follow Jan 23, 2025 · 6 mins read
Librariesandroid - hilt_hierarchy
Share this

Hilt

Hilt is a dependency injection library for Android that reduces the boilerplate of doing manual dependency injection in your project. Doing manual dependency injection requires you to construct every class and its dependencies by hand, and to use containers to reuse and manage dependencies.

Hilt provides a standard way to use DI in your application by providing containers for every Android class in your project and managing their lifecycles automatically. Hilt is built on top of the popular DI library Dagger to benefit from the compile-time correctness, runtime performance, scalability, and Android Studio support that Dagger provides.

With respect to Dagger, the goals of Hilt are as follows:

  • To simplify Dagger-related infrastructure for Android apps;
  • To create a standard set of components and scopes to ease setup, readability, and code sharing between apps;
  • To provide an easy way to provision different bindings to various build types, such as testing, debug, or release.

Because the Android operating system instantiates many of its own framework classes, using Dagger in an Android app requires you to write a substantial amount of boilerplate. Hilt reduces the boilerplate code that is involved in using Dagger in an Android application. Hilt automatically generates and provides the following:

  • Components for integrating Android framework classes with Dagger that you would otherwise need to create by hand;
  • Scope annotations to use with the components that Hilt generates automatically;
  • Predefined bindings to represent Android classes such as Application or Activity;
  • Predefined qualifiers to represent @ApplicationContext and @ActivityContext.

Hilt application class

All apps that use Hilt must contain an Application class that is annotated with @HiltAndroidApp.

@HiltAndroidApp triggers Hilt’s code generation, including a base class for your application that serves as the application-level dependency container.

@HiltAndroidApp
class ExampleApplication : Application() { ... }

This generated Hilt component is attached to the Application object’s lifecycle and provides dependencies to it. Additionally, it is the parent component of the app, which means that other components can access the dependencies that it provides.

Inject dependencies into Android classes

Once Hilt is set up in your Application class and an application-level component is available, Hilt can provide dependencies to other Android classes that have the @AndroidEntryPoint annotation:

@AndroidEntryPoint
class ExampleActivity : AppCompatActivity() { ... }

Hilt currently supports the following Android classes:

  • Application (by using @HiltAndroidApp)
  • ViewModel (by using @HiltViewModel)
  • Activity
  • Fragment
  • View
  • Service
  • BroadcastReceiver

If you annotate an Android class with @AndroidEntryPoint, then you also must annotate Android classes that depend on it. For example, if you annotate a fragment, then you must also annotate any activities where you use that fragment.

@AndroidEntryPoint generates an individual Hilt component for each Android class in your project. These components can receive dependencies from their respective parent classes as described in Component hierarchy.

To obtain dependencies from a component, use the @Inject annotation to perform field injection:

@AndroidEntryPoint
class ExampleActivity : AppCompatActivity() {

  @Inject lateinit var analytics: AnalyticsAdapter
  ...
}

Classes that Hilt injects can have other base classes that also use injection. Those classes don’t need the @AndroidEntryPoint annotation if they’re abstract.

Define Hilt bindings

To perform field injection, Hilt needs to know how to provide instances of the necessary dependencies from the corresponding component. A binding contains the information necessary to provide instances of a type as a dependency.

One way to provide binding information to Hilt is constructor injection. Use the @Inject annotation on the constructor of a class to tell Hilt how to provide instances of that class:

class AnalyticsAdapter @Inject constructor(
  private val service: AnalyticsService
) { ... }

The parameters of an annotated constructor of a class are the dependencies of that class. In the example, AnalyticsAdapter has AnalyticsService as a dependency. Therefore, Hilt must also know how to provide instances of AnalyticsService.

Hilt modules

Sometimes a type cannot be constructor-injected. This can happen for multiple reasons. For example, you cannot constructor-inject an interface. You also cannot constructor-inject a type that you do not own, such as a class from an external library. In these cases, you can provide Hilt with binding information by using Hilt modules.

A Hilt module is a class that is annotated with @Module. Like a Dagger module, it informs Hilt how to provide instances of certain types. Unlike Dagger modules, you must annotate Hilt modules with @InstallIn to tell Hilt which Android class each module will be used or installed in.

Dependencies that you provide in Hilt modules are available in all generated components that are associated with the Android class where you install the Hilt module.

Component lifetimes

Hilt automatically creates and destroys instances of generated component classes following the lifecycle of the corresponding Android classes.

Generated component Created at Destroyed at
SingletonComponent Application#onCreate() Application#onDestroy()
ActivityRetainedComponent Activity#onCreate() Activity#onDestroy()
ViewModelComponent ViewModel created ViewModel destroyed
ActivityComponent Activity#onCreate() Activity#onDestroy()
FragmentComponent Fragment#onAttach() Fragment#onDestroy()
ViewComponent View#super() View destroyed
ViewWithFragmentComponent View#super() View destroyed
ServiceComponent Service#onCreate() Service#onDestroy()

Component hierarchy

Installing a module into a component allows its bindings to be accessed as a dependency of other bindings in that component or in any child component below it in the component hierarchy:

Links

Dependency injection with Hilt

Further reading

Dependency injection on Android with Hilt
Scoping in Android and Hilt
Hilt — Adding components to the hierarchy
Migrating the Google I/O app to Hilt

credit goes to @swayangjit
Join Newsletter
Get the latest news right in your inbox. We never spam!
Upendra
Written by Upendra Follow
Hi, I am Upendra, the author in Human and machine languages,I don't know to how 3 liner bio works so just Connect with me on social sites you will get to know me better.