Dagger 是一個由 Google 維護,支援 Java 和 Kotlin 的依賴注入 (Dependency Injection, DI)套件,而 Hilt 則是基於 Dagger 的、專門針對 Android 平台的 DI 套件
(org.jetbrains.kotlin.android 和 com.google.devtools.ksp 也是必要的)
在 build.gradle.kts (Module :app) 的最上面,加入 com.google.dagger.hilt.android:
(com.google.devtools.ksp 也是必要的)
在 build.gradle.kts (Module :app) 的下半部,加入以下程式碼
程式入口點要加上 @AndroidEntryPoint 標記:
然後在 AndroidManifest.xml 加上這一行:
這樣在 MainActivity 中就可以使用 DI,不過所有依賴 MainActivity 類別的其他類別不管有沒有使用 DI 都需要加上 @AndroidEntryPoint 標記,包含以下幾種:
建立一個 UserService 服務:
(一定要加入 @Inject constructor() )
在 MainActivity 中透過 DI 自動取得 UserService 實例:
(雖然說 Kotlin 的單例只要把 class 換成 object 即可,不過這裡只是簡單的示範)
我們可以建立 DatabaseModule.kt (通常會放在 di package 下) 來自訂該如何實例化:
使用也非常簡單:
參考資料:
Dagger
Dagger KSP
Android Developers - Dependency injection in Android
安裝(使用 KSP)
在 build.gradle.kts(Project) 檔案下面加入 com.google.dagger.hilt.android :(org.jetbrains.kotlin.android 和 com.google.devtools.ksp 也是必要的)
plugins {
id("com.android.application") version "8.2.2" apply false
id("org.jetbrains.kotlin.android") version "1.9.0" apply false
id("com.google.devtools.ksp") version "1.9.0-1.0.13" apply false
id("com.google.dagger.hilt.android") version "2.50" apply false
}
在 build.gradle.kts (Module :app) 的最上面,加入 com.google.dagger.hilt.android:
(com.google.devtools.ksp 也是必要的)
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("com.google.devtools.ksp")
id("com.google.dagger.hilt.android")
}
在 build.gradle.kts (Module :app) 的下半部,加入以下程式碼
dependencies {
implementation("com.google.dagger:hilt-android:2.50")
ksp ("com.google.dagger:hilt-android-compiler:2.50")
}
使用
使用 Hilt 的所有應用程式都必須包含標記 @HiltAndroidApp 的 Application 類別,這裡建立一個自訂的 Application 類別
@HiltAndroidApp
class MainApplication : Application() {
}
程式入口點要加上 @AndroidEntryPoint 標記:
@AndroidEntryPoint
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
}
然後在 AndroidManifest.xml 加上這一行:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:name=".MainApplication"
>
</application>
</manifest>
這樣在 MainActivity 中就可以使用 DI,不過所有依賴 MainActivity 類別的其他類別不管有沒有使用 DI 都需要加上 @AndroidEntryPoint 標記,包含以下幾種:
- Activity
- Fragment
- View
- Service
- BroadcastReceiver
- Application: @HiltAndroidApp
- ViewModel: @HiltViewModel
建立一個 UserService 服務:
(一定要加入 @Inject constructor() )
class UserService @Inject constructor() {
fun getUserName(): String {
return "Ruyut"
}
}
在 MainActivity 中透過 DI 自動取得 UserService 實例:
@AndroidEntryPoint
class MainActivity : ComponentActivity() {
@Inject lateinit var userService: UserService
private val TAG = "MainActivity"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val userName = userService.getUserName()
Log.i(TAG, "onCreate: $userName")
}
}
(雖然說 Kotlin 的單例只要把 class 換成 object 即可,不過這裡只是簡單的示範)
Room 使用 Hilt DI 示範
假設我們有 AppDatabase :
@Database(
entities = [
UserEntity::class,
], version = 1
)
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
}
我們可以建立 DatabaseModule.kt (通常會放在 di package 下) 來自訂該如何實例化:
@Module
@InstallIn(SingletonComponent::class)
object DatabaseModule {
@Singleton
@Provides
fun provideDataBase(@ApplicationContext context: Context): AppDatabase {
return Room.databaseBuilder(
context.applicationContext,
AppDatabase::class.java,
"Tasks.db"
).build()
}
}
使用也非常簡單:
@Inject lateinit var userService: UserService
參考資料:
Dagger
Dagger KSP
Android Developers - Dependency injection in Android
留言
張貼留言
如果有任何問題、建議、想說的話或文章題目推薦,都歡迎留言或來信: a@ruyut.com