Using Hilt for dependency injection helps your app start faster by managing object creation efficiently. It reduces redundant object creation, which saves memory and CPU. This leads to smoother UI rendering and better battery life because your app avoids unnecessary work during runtime.
Dependency injection with Hilt in Android Kotlin - Build, Publish & Deploy
To keep your app running at 60fps, avoid injecting heavy objects directly into UI components. Instead, inject lightweight interfaces or use lazy injection to create objects only when needed. Also, scope your dependencies properly (e.g., Singleton, ActivityScoped) to reuse instances and reduce memory overhead.
Adding Hilt increases your app size slightly due to generated code and annotations. Typically, this adds a few hundred kilobytes, which is small compared to the benefits. To minimize size, enable code shrinking (ProGuard/R8) which removes unused code and optimizes the final APK or AAB.
Hilt is specific to Android and Kotlin. iOS uses different dependency injection patterns, often manual or with Swift frameworks like Resolver or Needle. Android requires annotation processing for Hilt, while iOS uses compile-time Swift features. Understanding these platform differences helps when developing cross-platform apps.
Hilt itself does not affect store guidelines directly. However, ensure your app complies with Google Play policies on performance and security. Avoid injecting sensitive data directly; use secure storage. Also, keep your app responsive and avoid long startup delays caused by heavy dependency initialization.
Your app takes 5 seconds to load this screen. What's likely wrong?
- Heavy dependencies are created eagerly on the main thread instead of lazily.
- Incorrect scoping causes multiple instances, increasing memory and startup time.
- Annotation processing or generated code is not optimized or ProGuard/R8 is disabled.
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
