Demystifying Hilt: How and Why Objects Flow Through Your Android App
What is Hilt?
Demystifying Hilt: How and Why Objects Flow Through Your Android App
What is Hilt?
Hilt is Dependency Injection library for android built on top of Dagger. We can think of Hilt as a system that automatically creates and provides the object your app needs, instead of you manually creating and passing them around everywhere.
Before understanding how Hilt helps us, let’s first see how dependency creation is usually handled without any Dependency Injection library.
Suppose we have an app that fetches user data from an API.
class ApiService {
fun getUsers(): List<String> {
return listOf("John", "Emma", "Alex")
}
}
class UserRepository {
private val apiService = ApiService()
fun fetchUsers(): List<String> {
return apiService.getUsers()
}
}
class MainViewModel {
private val repository = UserRepository()
fun loadUsers() {
val users = repository.fetchUsers()
println(users)
}
}
MainViewModel creates UserRepository. UserRepository creates ApiService.Each class is responsible for creating its own dependencies.This may look fine for small projects, but as the application grows, it starts creating problems.
Problems Without DI
- Tight Coupling:
MainViewModelis tightly coupled toUserRepository.UserRepositoryis tightly coupled toApiService.This makes the code less flexible and harder to modify. - Difficult Testing:Imagine you want to test
MainViewModel.You cannot easily replace the realUserRepositoryorApiServicewith fake/mock versions because the objects are created internally. - Duplicate Object Creation: Every time a new class creates
ApiService, a new instance is created.In real apps, this can waste memory and resources.
The Core Problem
The main issue is:Classes should not be responsible for creating their own dependencies.They should only focus on their actual job.UserRepository should manage user data not decide how ApiService is created. This is exactly where Dependency Injection and Hilt help us.
A Better Approach — Dependency Injection
Instead of creating dependencies inside the class, we provide them from outside.
class UserRepository(
private val apiService: ApiService
)
Now UserRepository no longer cares:
- where
ApiServicecomes from - how it is created
- whether it is a real or fake implementation
It simply receives what it needs and focuses only on its responsibility.This concept is called Dependency Injection (DI).
Where Hilt Comes In
Dependency Injection improves architecture, but managing dependencies manually can still require a lot of boilerplate code. This is where Hilt helps.
Hilt automates:
- object creation
- dependency management
- lifecycle handling
- dependency sharing
so developers can focus more on building features instead of wiring dependencies manually.
Setting Up Hilt in an Android Project
Now that we understand the basics of Dependency Injection, let’s set up Hilt in an Android project and understand why each configuration is required.
Hilt works on top of Dagger and generates a lot of code automatically during compilation. That’s why some setup is necessary before we can start injecting dependencies.
Step 1 — Add Hilt Dependencies
Project-Level build.gradle
plugins {
id("com.google.dagger.hilt.android") version "2.57.1" apply false
}
This adds the Hilt Gradle plugin to the project.The plugin is responsible for:
- generating dependency injection code
- creating Hilt components automatically
- connecting Android lifecycle components with Dagger
Without this plugin:
- Hilt annotations like
@HiltViewModel @AndroidEntryPoint@HiltAndroidApp
would not work because the required generated code would never be created.
Step 2 — Add Hilt Dependencies in App Module
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
// KSP plugin for annotation processing
id("com.google.devtools.ksp")
// Hilt Gradle plugin
id("com.google.dagger.hilt.android")
}
dependencies {
// Main Hilt library
implementation("com.google.dagger:hilt-android:2.57.1")
// Hilt compiler for code generation
ksp("com.google.dagger:hilt-compiler:2.57.1")
// Hilt support for Jetpack Compose Navigation
implementation("androidx.hilt:hilt-navigation-compose:1.2.0")
}
Hilt Gradle Plugin
id("com.google.dagger.hilt.android")
This plugin connects Hilt with the Android build system.It is responsible for:
- generating dependency injection code
- creating Hilt components automatically
- integrating Hilt with Android lifecycle classes
Without this plugin:
- annotations like
@AndroidEntryPoint @HiltViewModel@HiltAndroidApp
will not work correctly because the required generated code will be missing.
Main Hilt Library
implementation("com.google.dagger:hilt-android:2.57.1")
This is the core Hilt library.It contains:
- Hilt annotations
- dependency injection APIs
- Android integration support
- lifecycle-aware components
This library gives us access to features like:
@Inject@HiltViewModel@AndroidEntryPoint
Without it, Hilt functionality is unavailable.
Hilt Compiler
ksp("com.google.dagger:hilt-compiler:2.57.1")
Hilt works using code generation.
The compiler:
- reads annotations like
@Inject - analyzes dependency relationships
- generates factories and dependency graphs automatically
For example, when Hilt sees:
@Inject constructor()
it generates the code required to create that object automatically.
Without the compiler:
- Hilt cannot generate dependency code
- injection will fail at compile time
Hilt Navigation Compose
implementation("androidx.hilt:hilt-navigation-compose:1.2.0")
This dependency provides Hilt integration with Jetpack Compose navigation.
It allows us to use ViewModels easily inside Compose screens:
val viewModel: UserViewModel = hiltViewModel()
Step 3 — Create the Application Class
@HiltAndroidApp
class MyApplication : Application()
Why Is @HiltAndroidApp Required?
This is one of the most important annotations in Hilt.
When you add:
@HiltAndroidApp
Hilt generates:
- the application-level dependency container
- the root Dagger component
Think of it as:“Start Hilt for the entire app.”
Without this annotation:
- Hilt cannot initialize
- dependency injection will not work anywhere in the app
Step 4 — Register Application Class in Manifest
<application
android:name=".MyApplication"
...
</application>
Why Is This Required?
Android must know which Application class to start when the app launches.
If we don’t register it:
- Android uses the default
Application - Hilt initialization never happens
So even though we created MyApplication, Android would ignore it.
Step 5 — Create a Repository
class UserRepository @Inject constructor() {
fun getUsers(): List<String> {
return listOf("John", "Emma", "Alex")
}
}
Why Is @Inject constructor() Required?
This tells Hilt:“You are allowed to create this class automatically.”
Without @Inject:
- Hilt does not know how to construct
UserRepository
Hilt needs instructions for creating dependencies.
Step 6 — Create ViewModel with @HiltViewModel
@HiltViewModel
class UserViewModel @Inject constructor(
private val repository: UserRepository
) : ViewModel() {
fun loadUsers(): List<String> {
return repository.getUsers()
}
}
Why Is @HiltViewModel Required?
ViewModels are managed by Android’s lifecycle system.Normally Android creates ViewModels itself.
Hilt needs this annotation to:
- integrate with the ViewModel lifecycle
- create the ViewModel using dependency injection
- survive configuration changes properly
Without @HiltViewModel:
- Hilt cannot inject dependencies into the ViewModel
Step 7 — Enable Injection in Activity
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
private val viewModel: UserViewModel by viewModels()
}
Why Is @AndroidEntryPoint Required?
Android components like:
- Activity
- Fragment
- Service
are created by the Android framework, not by Hilt. So Hilt needs permission to inject dependencies into them.
@AndroidEntryPoint tells Hilt:“This Android class participates in dependency injection.”Without it:
- injected dependencies cannot be provided
- ViewModel injection will fail
What Happens Behind the Scenes?
When the app starts:
- Hilt initializes the dependency container
- Hilt generates dependency graphs
- Hilt creates
UserRepository - Hilt creates
UserViewModel - Hilt injects dependencies automatically
- Android receives ready-to-use objects
All of this happens with minimal boilerplate.
메타데이터
- post_id
- 40e40b623cdc
- slug
- demystifying-hilt-how-and-why-objects-flow-through-your-android-app-40e40b623cdc
- url
- https://medium.com/@kanhaiya.yadav47/demystifying-hilt-how-and-why-objects-flow-through-your-android-app-40e40b623cdc
- canonical_url
- https://medium.com/@kanhaiya.yadav47/demystifying-hilt-how-and-why-objects-flow-through-your-android-app-40e40b623cdc
- author_url
- https://medium.com/@kanhaiya.yadav47
- status
- ok
- fetched_at
- 2026-06-24 04:09:36