Chapters

Hide chapters

Dagger by Tutorials

First Edition · Android 11 · Kotlin 1.4 · AS 4.1

18. Hilt & Architecture Components
Written by Massimo Carli

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

In the previous chapter, you learned how to migrate the Busso App from Dagger Android to Hilt. You saw the main Hilt architectural decisions and how to apply them using new APIs like @InstallIn and @AndroidEntryPoint.

In this chapter, you’ll learn more about Hilt, including how to:

  • Use Hilt with other supported Android standard components, like Services.
  • Create custom Hilt @Endpoints for currently unsupported Android standard components, like ContentProviders.
  • Use Hilt with ViewModels.

Throughout the chapter, you’ll work with the RayTrack app. Don’t worry about the amount of code the app has. It’s purposely a complex app, to give you the opportunity to work with Hilt’s architectural components. You’ll only focus on the things that have to do with Hilt. To save space, you’ll only see the most relevant parts of the code in this chapter.

Note: An interesting exercise would be to simplify RayTrack’s code. Check the project for the full code.

Note: This chapter requires knowledge of the main Android Architecture Components, like Lifecycle, ViewModel and LiveData.

The RayTrack app

In this chapter, you’ll work on RayTrack. Use Android Studio to open the RayTrack project in the starter folder for this chapter. You’ll see the project structure shown in Figure 18.1:

Figure 18.1 — Starting RayTrack project
Figure 18.1 — Starting RayTrack project

RayTrack has some modules in common with Busso:

  • libs.di.scope
  • libs.location.api
  • libs.ui.navigation

It also has some new modules:

  • libs.location.api-android
  • libs.location.flow

These are just a different implementation of the abstraction you have in libs.location.api for Android. They use Kotlin Flows and coroutines.

Build and run and you’ll get, after the splash screen and permission request, something like in Figure 18.2:

Figure 18.2 — RayTrack in Action
Figure 18.2 — RayTrack in Action

Yeah, the UI isn’t the best, but the RayTrack app does what you need. :] When you press the Start Tracking button, you start a Foreground Service that keeps track of your current location and stores it in a database. Pressing the Stop Tracking button while the tracking is running stops the service. While the service is running, you can also see the location in the notification area:

Figure 18.3 — RayTrack Notification
Figure 18.3 — RayTrack Notification

Selecting the notification area returns you to the list of locations shown in Figure 18.2. Finally, you can select the Clear Data button and delete the database content at any time.

Now that you know how RayTrack works, it’s time to see how it’s set up.

RayTrack’s architecture

RayTrack consists of three main parts:

Tracking location data in the foreground

RayTrack uses Service to track the user’s location. Because the user’s location is sensitive data, Android requires you to implement this as a foreground service so the user always knows when it’s running on their device.

Heteku 39.1 — Bxi QmehbaxjBojyupe
Fojugu 02.2 — Vmi TcacleqgCicsomi

Injecting dependencies

Open TrackingService.kt in raytracker.service and look at the following code:

Huyapu 39.1 — Sacqawf qaalzal
Yeyelu 35.4 — Lefyicn yeocjij

Persisting location data

In the previous paragraph, you saw how to inject dependencies in TrackingService. You discovered that the dependency injection in a Service with Hilt is no different from the injection in an Activity, a Fragment or any other component Hilt supports.

Understanding the role of ContentProvider in RayTrack

RayTrack uses a ContentProvider to persist location data. To understand how this works, look at the diagram in Figure 18.6:

Faloki 08.1 — CajLwayk tiwgekzeylu
Kezaxo 87.7 — FuzWdafn jusnumzikvo

Creating a custom @EntryPoint

As you learned, Hilt doesn’t support ContentProviders as a predefined @AndroidEntryPoint — but it gives you tools to work around that. That’s what you’ll do for RayTrackContentProvider.

Adding bindings

To start, open TrackDBModule.kt in di and add:

Defining an entry point

Next, open RayTrackContentProvider.kt in repository.contentprovider and add the following code:

Accessing TrackDatabase

Finally, you need to access TrackDatabase in RayTrackContentProvider. In RayTrackContentProvider.kt in repository.contentprovider, replace the existing getRoomDatabase() with:

Displaying the location data

RayTrack can display the location data on the screen. The diagram in Figure 18.7 describes the current architecture:

Gebura 38.2 — Omavr GoyholyXodeleilPeecFoqom oc KoefOrmucivt
Hogufe 36.0 — Ikitp BeyzawzLufiyiuvMauqNeyay ap TeodOztupahs

Adding VieModel support for Hilt

To add ViewModel support for Hilt, you need to extend the annotation processor. Open build.gradle for app and add the following dependencies:

Using @ViewModelInject in your ViewModel implementation

Open CurrentLocationViewModel.kt in ui.main and look at the following header:

Injecting your ViewModel implementation in MainActivity

For your final step, you need to improve MainActivity. Open MainActivity.kt in ui.main and replace it with:

Yemako 92.9 — Imnotditt BottetyHujugeolCuohJiwur am PaoxUqlejekv
Bofodi 36.0 — Ibjamvips LepyejnRaxuqeadXoezXexoy in SeutUlcixukw

Creating a custom @Component with @DefineComponent

Earlier, you learned that Hilt doesn’t support all the Android standard components as @AndroidEntryPoints. That’s why you had to use @EntryPoint with RayTrackContentProvider. In that case, you wanted to inject TrackDatabase, which is an object in ApplicationComponent, with @Singleton — or your alias, @ApplicationContext — scope.

Creating a custom @Scope

Each @Component Hilt supports has a specific @Scope, so the custom @Component you’ll create needs one as well. You already know how to do this. Just create a new package named custom in di and, inside, add a new file named TrackRunningScoped.kt with the following code:

Creating a custom @Component using @DefineComponent

The next step is to create the custom @Component. In the same di.custom package, create a new file named TrackRunningComponent.kt and add the following code:

Tahuma 48.4 — Qidray Wucyocehs Maamiwjws
Hopaxa 18.7 — Japzuv Cuytavitg Kaeracthh

Adding a @DefineComponent.Builder

Hilt requires you to manage the lifecycle of the custom @Component and wants you to provide a Builder to use to create the @Component instance. To do this, open TrackRunningComponent.kt and add the following code:

Managing @DefineComponent’s lifecycle

What differentiates each @Component from the others is its lifecycle. As you’ve learned, objects in ApplicationComponent live as long as the entire Application, while objects in ActivityComponent live as long as a specific Activity, and so on. This means that TrackRunningComponent should have a lifecycle you should manage.

Adding bindings to the custom @Component with @EntryPoint

For an example of a TrackRunningScoped object, think of a simple Logger.

Using the custom @Component in your code

Your final step is to use HiltLogger in MainActivity. Open MainActivity.kt in ui.main and apply the following change:

Key points

  • Hilt currently doesn’t support all the Standard Android Components as @AndroidEntryPoints.
  • An @EntryPoint allows you to inject bindings into components Hilt doesn’t support yet.
  • You can create a custom @Component using @DefineComponent.
  • @DefineComponent needs a parent that allows you to extend the default Hilt @Component hierarchy.
  • Hilt provides a library to help you use dependency injection with ViewModel.
Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.
© 2026 Kodeco Inc.

You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now