
【Android Hilt 依賴注入完整教學】系列文章目錄:連結
Youtube 教學頻道:HKT線上教室
今天要跟大家分享的是如何在 Android 專案中使用 Hilt 框架來實現建構子注入(Constructor Injection)。
建構子注入是依賴注入中最推薦的注入方式,因為它:
- 確保物件在建立時就擁有所有必要的依賴
- 使依賴關係更加明確且容易追蹤
- 有助於單元測試的編寫
- 在編譯時就能發現潛在問題
前言
在上一篇文章中,我們討論了成員注入(Member Injection)或欄位注入(Field Injection)的實作方式。今天要更進一步,介紹另一種更優雅的注入方式:建構子注入。
補充:什麼是建構子(Constructor)?
建構子(Constructor)是一個特殊的方法,用於初始化類別的新實例。它具有以下特點:
- 命名規則:
- 建構子的名稱必須與類別名稱相同
- 在 Kotlin 中使用 constructor 關鍵字宣告
- 可以有多個建構子(稱為多載)
- 執行時機:
- 在物件被建立時自動執行
- 負責初始化物件的狀態
- 設定必要的屬性值
- 建構子的類型:
- 主要建構子(Primary Constructor)
- 次要建構子(Secondary Constructor)
- 無參數建構子(Default Constructor)
- 在依賴注入中的重要性:
- 是實現建構子注入的關鍵
- 透過建構子參數明確表達依賴關係
- 確保物件在建立時就擁有所需的所有依賴
建構子注入基礎
讓我們從一個簡單的例子開始:
class Product @Inject constructor(
private val alertSystem: AlertSystem
)
在這個例子中,我們使用 @Inject
標註建構子,這樣 Hilt 就知道如何建立 Product
物件。但是要注意,我們不能直接在建構子中建立 AlertSystem
的實例,而是要讓 Hilt 來處理這個依賴關係。
相依類別的設定
為了讓 Hilt 知道如何提供 AlertSystem
,我們需要在 AlertSystem
類別中也加入 @Inject
標註:
class AlertSystem @Inject constructor() {
fun alert() {
println("Alerting...")
}
}
進階應用:Context 注入
在實際開發中,我們常常需要使用 Android 的 Context
。以下示範如何在 Hilt 中注入 Context:
class AlertSystem @Inject constructor(
@ApplicationContext private val context: Context
) {
fun alert() {
val message = context.getString(R.string.hello_world)
println(message)
println("Alerting...")
}
}
注意事項:
- Context 注入的標註選擇:
- 使用
@ApplicationContext
標註可以注入 Application Context: - 適用於需要應用程式級別 Context 的場景
- Application Context 的生命週期與應用程式相同
- 適合用於單例模式的服務或工具類別
- 使用
@ActivityContext
注入 Activity Context: - 適用於需要 Activity 相關功能的場景
- 例如:顯示 Dialog、啟動新的 Activity
- 需要特別注意生命週期管理
- 使用
- Context 的生命週期管理:
- 避免在長壽命的物件中持有短壽命的 Context 引用
- 常見的記憶體洩漏情況:
- 在單例物件中儲存 Activity Context
- 在背景執行緒中持有 Activity Context
- 在靜態變數中保存 Context 引用
- 建議的做法:
- 優先使用 Application Context
- 需要 Activity Context 時,確保其生命週期不會超過 Activity
- 使用 WeakReference 來持有 Context 引用
- 最佳實踐建議:
- 明確區分 Context 的使用場景
- 在文件中註明使用的 Context 類型
- 定期檢查記憶體洩漏
- 使用工具(如 LeakCanary)來監測記憶體洩漏
重要觀念
- 解耦合(Decoupling):依賴注入的最大優點是將物件的建立與使用分離
- 生命週期管理:使用適當的 Context 標註來確保正確的生命週期管理
- 程式碼可測試性:依賴注入讓我們的程式碼更容易進行單元測試
下一步
在下一篇文章中,我們將深入探討 Hilt Modules 的使用方式,包含:
- Module 的基本概念與使用時機
- @Provides 與 @Binds 的差異與使用場景
- 如何使用 Module 提供介面的實作
- Module 的作用域管理
- 多 Module 之間的相依關係處理
透過這些進階概念的學習,您將能夠:
- 更靈活地管理複雜的依賴關係
- 提供無法使用建構子注入的依賴
- 實現更好的程式碼模組化
- 優化應用程式的效能與記憶體使用