在 Android 專案中使用 Hilt Modules 模組化開發指南

更新於 發佈於 閱讀時間約 9 分鐘
raw-image
【Android Hilt 依賴注入完整教學】系列文章目錄:連結
Youtube 教學頻道:HKT線上教室

今天要跟大家分享的是如何在 Android 專案中使用 Hilt Modules。這是一個非常重要的主題,因為 Modules 是 Hilt 依賴注入框架中用於組織和提供依賴的核心機制。透過 Modules,我們可以更有效地管理複雜的依賴關係,提供介面的具體實作,以及控制物件的生命週期。本文將深入探討 Modules 的概念、使用時機與實作方式,幫助您更好地運用這個強大的功能。

Hilt Modules 是什麼?

Hilt Modules 本質上是一個類別,用於告訴 Hilt 框架如何建立和管理物件的生命週期。當我們需要注入的對象是介面(Interface)或是抽象類別時,Modules 就特別重要,因為 Hilt 需要知道具體要建立哪個實作類別。

Modules 在 Hilt 中扮演著以下重要角色:

  1. 提供依賴的來源:
    • 當無法直接使用建構子注入時(如第三方函式庫的類別)
    • 需要在建立物件時進行額外設定
    • 需要根據不同條件提供不同實作
  2. 管理物件生命週期:
    • 可以指定物件的作用域(Scope)
    • 控制物件是否為單例(Singleton)
    • 決定物件的重用策略
  3. 模組化程式碼:
    • 將相關的依賴設定集中管理
    • 提高程式碼的可維護性
    • 方便測試時替換實作

使用時機:

  • 需要注入介面或抽象類別的實作
  • 需要注入第三方函式庫的類別
  • 需要在建立物件時進行複雜的初始化
  • 需要根據不同環境(如測試/正式)提供不同實作

實作範例

讓我們透過一個實際的範例來了解:

// 定義一個介面
interface AlertSystem {
fun startAlerting()
}

// 實作介面
class NoiseAlertSystem(private val context: Context) : AlertSystem {
override fun startAlerting() {
println(context.getString(R.string.test_string))
}
}

// 建立 Module
@Module
@InstallIn(ActivityComponent::class)
object AlertSystemModule {
@Provides
fun provideAlertSystem(@ApplicationContext context: Context): AlertSystem {
return NoiseAlertSystem(context)
}
}

重要觀念說明

1. Module 的生命週期

使用 @InstallIn 註解來指定 Module 中提供的依賴項的生命週期範圍:

  • SingletonComponent:整個應用程式生命週期
    • 適用於全域性的服務或工具類別
    • 物件會在應用程式啟動時建立,直到應用程式結束才會銷毀
    • 需要謹慎使用,因為會佔用記憶體直到應用程式結束
    • 例如:資料庫實例、網路客戶端、共用偏好設定管理器
  • ActivityComponent:Activity 生命週期
    • 每個 Activity 都會有自己的實例
    • 物件會在 Activity 建立時產生,Activity 結束時銷毀
    • 適用於與特定 Activity 相關的功能
    • 例如:Activity 專用的 Presenter、特定畫面的資料管理器
  • ViewModelComponent:ViewModel 生命週期
    • 跟隨 ViewModel 的生命週期
    • 在螢幕旋轉等組態變更時會保持存活
    • 適合處理 UI 相關的資料和邏輯
    • 例如:表單資料暫存、畫面狀態管理
  • FragmentComponent:Fragment 生命週期
    • 每個 Fragment 擁有獨立的實例
    • 隨 Fragment 的建立和銷毀而生滅
    • 適用於 Fragment 特定的功能需求
    • 例如:Fragment 的視圖控制器、局部資料管理

注意事項:

  1. 選擇適當的 Component 對於記憶體管理和效能優化很重要
  2. 避免在較長生命週期的 Component 中持有較短生命週期的物件引用
  3. 需要考慮物件的狀態管理和資源釋放

2. 提供依賴的方法

在 Module 中,我們使用 @Provides 註解來標記提供依賴的方法。這個方法需要:

  1. 明確的回傳型別:
    • 必須明確指定方法要提供的依賴類型
    • 可以是具體類別或介面
    • Hilt 會根據這個型別來解析依賴關係
    • 同一個型別如果有多個提供者,需要使用限定符(Qualifier)區分
  2. 必要的參數(如果需要):
    • 方法可以接受其他依賴作為參數
    • 這些參數也必須能被 Hilt 提供
    • 常見的參數包括:
      • Context(需要適當的限定符)
      • 其他被 @Inject 或 @Provides 標記的依賴
      • 配置參數(如 API URL、資料庫名稱等)
  3. 方法命名建議:
    • 使用 provide 作為前綴
    • 清楚表達提供的依賴類型
    • 如果同一型別有多個提供者,名稱要能區分用途
  4. 提供方法的特性:
    • 必須是非抽象的具體方法
    • 可以包含初始化邏輯
    • 可以進行條件判斷
    • 可以整合多個依賴

使用情境

Hilt Modules 特別適用於以下情況:

  1. 需要注入介面的實作
    • 當您有一個介面和多個實作類別時
    • 可以在 Module 中指定要使用哪個實作
    • 例如:不同的資料來源介面(API、資料庫、快取)
    • 方便在測試時替換成測試用的實作
  2. 需要注入第三方函式庫的類別
    • 對於無法修改源碼的第三方元件
    • 需要為第三方類別提供初始化設定
    • 例如:Retrofit、Room Database、OkHttpClient
    • 可以在 Module 中封裝所有相關設定
  3. 需要在建立物件時進行額外的設定
    • 當物件需要複雜的初始化邏輯
    • 需要多個參數或相依物件來建立實例
    • 例如:設定 API 金鑰、資料庫連線參數
    • 可以將初始化邏輯集中在一處管理
  4. 需要管理物件的生命週期
    • 控制物件的作用域和存活時間
    • 決定是否要重複使用相同實例
    • 例如:單例模式的資料庫連線
    • 可以使用作用域註解(@Singleton、@ActivityScoped 等)
  5. 需要條件式提供不同實作
    • 根據執行環境選擇不同實作
    • 依據使用者設定切換實作
    • 例如:開發/正式環境的 API 端點
    • 可以使用限定符(Qualifier)來區分

注意事項

  1. 確保 @InstallIn 使用正確的 Component:
    • SingletonComponent:應用程式級別的依賴
    • ActivityComponent:Activity 範圍的依賴
    • FragmentComponent:Fragment 範圍的依賴
    • ViewComponent:View 範圍的依賴
    • ServiceComponent:Service 範圍的依賴
    • 使用錯誤的 Component 可能導致生命週期問題
  2. 留意依賴的生命週期管理:
    • 使用適當的作用域註解(@Singleton、@ActivityScoped 等)
    • 避免將短生命週期的物件注入到長生命週期的物件中
    • 注意記憶體洩漏的可能性
    • 定期使用工具(如 LeakCanary)檢查記憶體洩漏
  3. 如果遇到錯誤,仔細檢查錯誤訊息,找出依賴鏈中的問題:
    • 常見錯誤類型:
      • 循環依賴(Circular dependency)
      • 缺少必要的依賴提供者
      • Component 層級不匹配
      • 作用域衝突
    • 解決方法:
      • 使用 Hilt 的除錯工具查看依賴圖
      • 檢查所有相關類別的註解是否正確
      • 確認所有依賴都有對應的提供者
      • 考慮重構依賴結構
  4. 模組設計建議:
    • 依功能或層級分割模組
    • 避免過大的模組
    • 確保模組之間的相依性清晰
    • 適當使用抽象化來增加彈性
  5. 效能考量:
    • 避免在 Module 中進行耗時操作
    • 合理使用作用域來重用物件
    • 注意記憶體使用量
    • 考慮使用延遲初始化(Lazy Injection)

下一步

在下一篇文章中,我們將探討如何在同一個介面提供多個實作,這在需要根據不同情境使用不同實作時特別有用。

avatar-img
13會員
258內容數
哈囉!歡迎光臨我的沙龍!我是 KT,一位對應用程式開發充滿熱情的開發者。在這個專屬空間,我將與您分享我在應用開發領域的深入學習心得和豐富的實戰經驗。如果您對應用程式開發技術同樣充滿好奇,渴望不斷探索新知,歡迎成為我們的會員,一起在應用程式開發的旅途上,探索更深層次的技術世界,享受學習的樂趣。
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
HKT實驗室 的其他內容
本篇文章分享如何在 Android 專案中使用 Hilt 框架實現建構子注入 (Constructor Injection)。補充什麼是建構子,建構子注入基礎與相依類別的設定與 Application 和 Activity Context 注入方式。
本篇文章分享如何在 Android 專案中使用 Hilt 框架實現欄位注入(Field Injection)。欄位注入是 Hilt 提供的一種依賴注入方式,允許開發者在類別的欄位上直接使用 @Inject 標註來進行注入。
本篇文章將深入介紹 Android Hilt 依賴注入的基本設定步驟,幫助開發者快速上手這個由 Google 官方推出的相依性注入框架。
本篇文章詳細說明了為何在評估 Dagger、Hilt 和 Koin 三個依賴注入框架後,選擇 Hilt 作為目前 Android 開發的最佳選擇。Hilt 在開發效率最佳化、Google 官方支援、繼承 Dagger 的優點並克服其缺點,以及相較於 Koin 的優勢等方面表現突出。
本篇文章介紹 Android 開發中的依賴注入(Dependency Injection,DI)概念,強調其在現代開發中的重要性。依賴注入能解決類別之間的緊密耦合問題,提升程式碼的可重用性、測試便利性及重構的容易性。文章中舉例說明了未使用依賴注入的缺陷,並展示了使用依賴注入的改良方案。
本文提供全面的 Android Hilt 依賴注入框架完整教學目錄,涵蓋基礎概念、注入方式、進階功能及測試實務。透過這些內容,開發者能夠深入理解並有效學習並運用 Android Hilt 進行依賴注入 Dependency Injection。
本篇文章分享如何在 Android 專案中使用 Hilt 框架實現建構子注入 (Constructor Injection)。補充什麼是建構子,建構子注入基礎與相依類別的設定與 Application 和 Activity Context 注入方式。
本篇文章分享如何在 Android 專案中使用 Hilt 框架實現欄位注入(Field Injection)。欄位注入是 Hilt 提供的一種依賴注入方式,允許開發者在類別的欄位上直接使用 @Inject 標註來進行注入。
本篇文章將深入介紹 Android Hilt 依賴注入的基本設定步驟,幫助開發者快速上手這個由 Google 官方推出的相依性注入框架。
本篇文章詳細說明了為何在評估 Dagger、Hilt 和 Koin 三個依賴注入框架後,選擇 Hilt 作為目前 Android 開發的最佳選擇。Hilt 在開發效率最佳化、Google 官方支援、繼承 Dagger 的優點並克服其缺點,以及相較於 Koin 的優勢等方面表現突出。
本篇文章介紹 Android 開發中的依賴注入(Dependency Injection,DI)概念,強調其在現代開發中的重要性。依賴注入能解決類別之間的緊密耦合問題,提升程式碼的可重用性、測試便利性及重構的容易性。文章中舉例說明了未使用依賴注入的缺陷,並展示了使用依賴注入的改良方案。
本文提供全面的 Android Hilt 依賴注入框架完整教學目錄,涵蓋基礎概念、注入方式、進階功能及測試實務。透過這些內容,開發者能夠深入理解並有效學習並運用 Android Hilt 進行依賴注入 Dependency Injection。
你可能也想看
Google News 追蹤
Thumbnail
現代社會跟以前不同了,人人都有一支手機,只要打開就可以獲得各種資訊。過去想要辦卡或是開戶就要跑一趟銀行,然而如今科技快速發展之下,金融App無聲無息地進到你生活中。但同樣的,每一家銀行都有自己的App時,我們又該如何選擇呢?(本文係由國泰世華銀行邀約) 今天我會用不同角度帶大家看這款國泰世華CUB
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
本章節旨在教導讀者如何在 Kotlin 中引入套件。將會涵蓋如何引用第三方套件,如何引用自定義模組,以及如何創建和引用自定義套件。此外,還會列出一些常用的套件,以供讀者參考。
本課程學習如何使用 Intent 傳遞整包資料。
Thumbnail
本課程學習如何在 Kotlin 程式碼檔案中,設定 ImageView 圖片元件,顯示本地端圖片。
本課程主要學習 Android Studio 建立初始(Empty View Activity)專案中的重要目錄資料夾和檔案。
本課程學習如何使用 Android Studio 中的導覽列功能,快速查看方法(function、method)。
本課程學習如何在 Android Studio 上建立手機模擬器。
本課程學習如何建立的第一個 Android Studio 應用程式專案:Hello World。
Thumbnail
根據初學者設計了 Kotlin 程式語言的基礎課程,從 Android Studio 到 Android App 開發,提供完整指引。由基礎開始,傳授開發技巧。課程分為三部分:環境安裝、常用元件與界面設計,以及高階技巧如 DataStore、Room 資料儲存與網路處理。
Thumbnail
現代社會跟以前不同了,人人都有一支手機,只要打開就可以獲得各種資訊。過去想要辦卡或是開戶就要跑一趟銀行,然而如今科技快速發展之下,金融App無聲無息地進到你生活中。但同樣的,每一家銀行都有自己的App時,我們又該如何選擇呢?(本文係由國泰世華銀行邀約) 今天我會用不同角度帶大家看這款國泰世華CUB
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
本章節旨在教導讀者如何在 Kotlin 中引入套件。將會涵蓋如何引用第三方套件,如何引用自定義模組,以及如何創建和引用自定義套件。此外,還會列出一些常用的套件,以供讀者參考。
本課程學習如何使用 Intent 傳遞整包資料。
Thumbnail
本課程學習如何在 Kotlin 程式碼檔案中,設定 ImageView 圖片元件,顯示本地端圖片。
本課程主要學習 Android Studio 建立初始(Empty View Activity)專案中的重要目錄資料夾和檔案。
本課程學習如何使用 Android Studio 中的導覽列功能,快速查看方法(function、method)。
本課程學習如何在 Android Studio 上建立手機模擬器。
本課程學習如何建立的第一個 Android Studio 應用程式專案:Hello World。
Thumbnail
根據初學者設計了 Kotlin 程式語言的基礎課程,從 Android Studio 到 Android App 開發,提供完整指引。由基礎開始,傳授開發技巧。課程分為三部分:環境安裝、常用元件與界面設計,以及高階技巧如 DataStore、Room 資料儲存與網路處理。