What if your app could magically get the right tools exactly when it needs them, without you lifting a finger?
Why Dependency injection with Hilt in Android Kotlin? - Purpose & Use Cases
Imagine building an Android app where every screen needs to create its own database, network client, and other helpers manually.
You have to write code to create these objects again and again in each part of your app.
This manual approach leads to lots of repeated code, making your app hard to maintain.
It's easy to make mistakes like creating multiple instances when you only need one, or forgetting to update all places when a dependency changes.
Dependency injection with Hilt automatically provides the right objects where you need them.
It manages object creation and sharing behind the scenes, so you write less code and avoid errors.
val db = Database(context) val repo = Repository(db) val viewModel = ViewModel(repo)
@Inject lateinit var viewModel: ViewModel // Hilt provides all dependencies automatically
Hilt lets you focus on your app's logic while it handles creating and sharing dependencies cleanly and efficiently.
In a shopping app, Hilt can provide a single shared network client and database instance to all screens without you writing extra setup code everywhere.
Manual dependency creation causes repeated code and bugs.
Hilt automates providing dependencies safely and cleanly.
This leads to easier, faster, and more reliable Android app development.
Practice
@HiltAndroidApp annotation in an Android application?Solution
Step 1: Understand the role of @HiltAndroidApp
This annotation is placed on the Application class to start Hilt's code generation and create the application-level dependency container.Step 2: Differentiate from other annotations
@AndroidEntryPoint marks Activities or Fragments, @Module defines providers, and @Inject is for injection points, so they do not setup the application container.Final Answer:
To trigger Hilt's code generation and setup the application-level dependency container -> Option CQuick Check:
@HiltAndroidApp = Setup app container [OK]
- Confusing @HiltAndroidApp with @AndroidEntryPoint
- Thinking @HiltAndroidApp is for Activities
- Using @HiltAndroidApp on modules
Solution
Step 1: Identify how to enable injection in Activity
Using@AndroidEntryPointon the Activity allows Hilt to generate necessary code for injection.Step 2: Inject dependencies inside Activity
Use@Inject lateinit varto declare dependencies that Hilt will provide automatically.Final Answer:
Annotate the Activity with @AndroidEntryPoint and use @Inject lateinit var for the dependency -> Option AQuick Check:
@AndroidEntryPoint + @Inject lateinit var = Activity injection [OK]
- Trying to use @Module on Activity
- Forgetting @AndroidEntryPoint annotation
- Injecting dependencies via constructor in Activity
repository.getData() is called?@Module
@InstallIn(SingletonComponent::class)
object DataModule {
@Provides
fun provideData(): String = "Hello Hilt"
}
class Repository @Inject constructor(private val data: String) {
fun getData() = data
}Solution
Step 1: Understand the provided dependency
The module provides a String "Hello Hilt" via the provideData() function.Step 2: Check Repository injection
Repository constructor is annotated with @Inject and receives the String dependency correctly.Final Answer:
"Hello Hilt" -> Option DQuick Check:
Provided String = "Hello Hilt" [OK]
- Assuming @Inject missing on Repository causes error (it is present)
- Confusing module name with provided value
- Expecting runtime null error without reason
@Module
@InstallIn(ActivityComponent::class)
object NetworkModule {
@Provides
fun provideRetrofit(): Retrofit {
return Retrofit.Builder().baseUrl("https://api.example.com").build()
}
}
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
@Inject lateinit var retrofit: Retrofit
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
}Solution
Step 1: Check the component scope for Retrofit
Retrofit is usually a singleton because it is expensive to create and shared across app.Step 2: Analyze the module's @InstallIn scope
The module is installed in ActivityComponent, which creates a new instance per Activity, not singleton.Step 3: Identify the mismatch
Providing Retrofit in ActivityComponent scope causes multiple instances, which is incorrect for Retrofit.Final Answer:
Retrofit cannot be provided in ActivityComponent scope because it should be Singleton -> Option AQuick Check:
Retrofit = Singleton scope needed [OK]
- Thinking Retrofit needs @Inject constructor
- Confusing @HiltAndroidApp with @AndroidEntryPoint
- Believing manual creation is required with @Provides
Logger using Hilt in your Android app. Which approach correctly distinguishes these implementations for injection?Solution
Step 1: Understand multiple implementations injection
When multiple implementations of the same interface exist, Hilt needs a way to distinguish them.Step 2: Use @Qualifier annotations
Custom @Qualifier annotations with different names allow Hilt to know which implementation to inject where.Step 3: Reject other options
Injecting List<Logger> is possible but does not distinguish single injection points; @Singleton does not differentiate implementations; separate modules without qualifiers cause ambiguity.Final Answer:
Use @Qualifier annotations with different names on each provider and injection site -> Option BQuick Check:
Multiple implementations = use @Qualifier [OK]
- Injecting interface without qualifiers causes errors
- Assuming @Singleton differentiates implementations
- Not using qualifiers when multiple providers exist
Ready to prove it?
Pass the test and this pattern moves unknown
