Hilt
Dependency Injection

Beberapa dependency injection di android yang umum dipakai:
- Dagger, jika sudah menguasai tentu baik memakai Dagger, cuma memang proses pembelajarannya lebih susah.
- Dagger Android, mengurangi boilerplate code pada Dagger, tapi kurang sukses, karena masih repot juga memakainya.
Baru — baru ini google membuat dependency injection yang baru yaitu Hilt.
Kenapa memakai Hilt
- Untuk mempermudah dependency injection bagi developer
- Mengurangi boilerplate.
- Setup lebih mudah dan mempermudah readability.
- Bisa untuk build varian yang berbeda.
Mengingat konsep Dagger
Ada 4 annotation yang digunakan pada dagger
- Module
- Component
- Provides
- Inject
Module menyediakan dependency yang akan digunakan oleh Consumer, bisa activity, fragment, atau kelas lain. Component sebagai fasilitator atau bridge antara provider dan consumer.

Setup Hilt
project build.gradle
buildscript {
...
dependencies {
...
classpath 'com.google.dagger:hilt-android-gradle-plugin:2.28-alpha'
}
}
app/build.gradle
...
apply plugin: 'kotlin-kapt'
apply plugin: 'dagger.hilt.android.plugin'
android {
...
}
dependencies {
implementation "com.google.dagger:hilt-android:2.28-alpha"
kapt "com.google.dagger:hilt-android-compiler:2.28-alpha"
}
Application
Application yang menggunakan hilt harus mempunyai kelas Application yang di annotate dengan @HiltAndroidApp
Ini untuk membuat hilt component yang akan digunakan di applikasi kita.
@HiltAndroidApp
class ExampleApplication : Application() { ... }
Consumer
Hilt menyediakan dependency kepada consumer, misalnya di activity dengan menggunakan annotation @AndroidEntryPoint
Jika di memakai dependecy di fragment maka activity nya juga harus diberi annotation.
@AndroidEntryPoint
class ExampleActivity : AppCompatActivity() { ... }
Catatan:
- Hilt hanya support activity yang extends dari ComponentActivity, seperti AppCompatActivity.
- Hilt hanya support fragment yang extends dari androidx.Fragment.
- Hilt tidak support retained fragment.
Untuk mendapatkan dependency dari component menggunakan annotation @Inject
@AndroidEntryPoint
class ExampleActivity : AppCompatActivity() {
@Inject lateinit var analytics: AnalyticsAdapter
...
}
Catatan : field yang di-inject oleh hilt tidak boleh private.
Kelas yang di inject
Agar hilt mengetahui kelas yang akan di inject : dengan menggunakan annotation @Inject pada constructor kelas tersebut.
class AnalyticsAdapter @Inject constructor(
private val service: AnalyticsService
) { ... }
Dalam contoh di atas kelas AnalyticsAdapter mempunyai dependency ke kelas AnalyticsService, maka hilt perlu mengetahui juga untuk menyediakan instance kelas AnalyticsService.
Tidak semua type bisa dengan menggunakan constructor injection, misalnya interface tidak bisa, ataupun type yang tidak kita buat sendiri, misal kelas dari external library.
Maka untuk memberitahu hilt perlu menggunakan module (Hilt Module). Annotation yang dipakai di module adalah @Module dan @InstallIn
Inject Interface instance dengan @Binds
Misal AnalyticsService adalah interface maka kita tidak bisa menggunakan constructor injection. Perlu membuat hilt module dan fungsi di dalam module tersebut yang di annotate dengan @Binds
interface AnalyticsService {
fun analyticsMethods()
}
// Constructor-injected, because Hilt needs to know how to
// provide instances of AnalyticsServiceImpl, too.
class AnalyticsServiceImpl @Inject constructor(
...
) : AnalyticsService { ... }
@Module
@InstallIn(ActivityComponent::class)
abstract class AnalyticsModule {
@Binds
abstract fun bindAnalyticsService(
analyticsServiceImpl: AnalyticsServiceImpl
): AnalyticsService
}
@Binds annotation memberi tahu hilt implementasi mana yang akan digunakan untuk menyediakan instance dari interface.
Pada contoh AnalyticsModule di atas mengunakan @InstallIn (ActivityComponent::class) artinya semua dependency yang disediakan AnalyticsModule akan tersedia untuk semua app activity.
Inject kelas instance dengan @Provides
Kelas yang tidak kita buat juga tidak bisa di inject dengan menggunakan constructor injection. Seperti kelas dari library.
Kita perlu membuat hilt module yang mempunyai fungsi yang menyediakan instance class yang akan di inject. Menggunakan @Provides annotation
@Module
@InstallIn(ActivityComponent::class)
object AnalyticsModule {
@Provides
fun provideAnalyticsService(
// Potential dependencies of this type
): AnalyticsService {
return Retrofit.Builder()
.baseUrl("https://example.com")
.build()
.create(AnalyticsService::class.java)
}
}
Catatan tambahan:
Dengan hilt tidak perlu membuat component seperti pada dagger.
Kesimpulan
- Hilt mengurangi boiler plate code untuk menerapkan dependency injection pada android. Dan juga lebih mudah untuk diterapkan karena kompleksitas dagger disembunyikan oleh hilt.
Pada tulisan ini kita belajar :
- Mengingat kembali konsep dagger.
- Mengapa memakai hilt.
- Bagaimana cara memakai hilt.