Dependency injection helps your app get the things it needs without creating them itself. Hilt makes this easy and organized in Android apps.
Dependency injection with Hilt in Android Kotlin
1. Add @HiltAndroidApp to your Application class. 2. Use @AndroidEntryPoint on Activities or Fragments. 3. Create modules with @Module and @InstallIn annotations. 4. Provide dependencies with @Provides or @Inject constructors. 5. Use @Inject to get dependencies in your classes.
@HiltAndroidApp triggers code generation for dependency injection setup.
@AndroidEntryPoint tells Hilt where to inject dependencies in Android components.
@HiltAndroidApp
class MyApp : Application()@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
@Inject lateinit var repository: UserRepository
}@Module @InstallIn(SingletonComponent::class) object NetworkModule { @Provides fun provideRetrofit(): Retrofit { return Retrofit.Builder().baseUrl("https://api.example.com").build() } }
class UserRepository @Inject constructor(private val retrofit: Retrofit) {
// Use retrofit here
}This example shows a simple Android app using Hilt. The GreetingService is provided by a module and injected into MainActivity. When the app runs, it prints a greeting message.
import android.app.Application import dagger.hilt.android.HiltAndroidApp @HiltAndroidApp class MyApp : Application() import androidx.activity.ComponentActivity import android.os.Bundle import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject @AndroidEntryPoint class MainActivity : ComponentActivity() { @Inject lateinit var greetingService: GreetingService override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) println(greetingService.greet()) } } import dagger.Module import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent import javax.inject.Singleton @Module @InstallIn(SingletonComponent::class) object GreetingModule { @Provides @Singleton fun provideGreetingService(): GreetingService = GreetingService() } class GreetingService { fun greet() = "Hello from Hilt!" }
Always add @HiltAndroidApp to your Application class once per app.
Use @AndroidEntryPoint on every Activity or Fragment where you want injection.
Modules define how to create objects that Hilt cannot create by itself.
Hilt helps manage dependencies automatically in Android apps.
Use annotations like @HiltAndroidApp, @AndroidEntryPoint, @Module, and @Inject.
This makes your code cleaner, easier to test, and reduces manual setup.
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
