從 Dagger 遷移到 Hilt 可帶來的收益

Hilt 發佈於 2020 年 6 月,爲 Android 提供了依賴項注入 (DI) 的標準化方案。對於新項目,Hilt 有着編譯期校驗,良好的運行時性能以及擴展性 (閱讀文章 Android 和 Hilt 中限定做用域,獲取更多信息)。然而,Hilt 對於已經使用 Dagger 的應用有何優點呢?您是否應該將現有的應用遷移到 Hilt 呢?如下幾點闡述了您的團隊須要投入精力到遷移工做中的緣由。html

✅ 支持 AndroidX 擴展android

若是您已經使用 Dagger 處理 ViewModel 或者 WorkManager,您就會知道,注入您本身的 ViewModelFactory 與 WorkerFactory 須要大量的模板代碼,而且須要 Dagger 相關知識。最多見的實現就是使用 多綁定,這是 Dagger 中最複雜的功能之一,開發人員每每難以理解。Hilt 經過移除模板代碼大大簡化了 AndroidX 的使用。更妙的是,您甚至無需對 Android Framework 的類注入 Factory,就好像沒有使用 Hilt 同樣。經過使用 @HiltViewModel,Hilt 爲您建立了正確的 ViewModelProvider.Factory,正因如此,被 @AndroidEntryPoint 註解的 Activity 和 Fragment 能夠直接使用。ios

@HiltViewModel
class PlayViewModel @Inject constructor(
  val db: MusicDatabase,
) : ViewModel() { ... }

@AndroidEntryPoint
class PlayActivity : AppCompatActivity() {

  val viewModel: PlayViewModel by viewModels()
  
  override fun onCreate(savedInstanceState: Bundle) {
    super.onCreate(bundle)
    viewModel.play()
  }
}

✅ 支持測試 API

DI (依賴項注入) 本應該使測試更加容易,但諷刺的是,使用 Dagger 進行測試須要 大量的工做。實際上,您必須同時維護正式和測試的 Dagger 關係圖,而 Hilt 的實現方式 則更加便捷。git

Hilt 測試可使用 @UninstallModules 功能顯式修改 DI 關係圖。除此以外,還提供了諸如 @BindValue 一類的其餘功能,能夠輕鬆地將測試字段綁定到 DI 關係圖中。github

@UninstallModules(AnalyticsModule::class)
@HiltAndroidTest
class ExampleTest {

  @get:Rule
  var hiltRule = HiltAndroidRule(this)
  
  @BindValue @JvmField
  val analyticsRepository = FakeAnalyticsRepository()
  
  @Test 
  fun myTest() { ... }
}

✅ 良好的一致性

在 Dagger 中有不少種方法能夠實現相同的功能。因爲早期缺少 Android 應用的指南文檔 (去年咱們已經解決了這一問題,例如指南文章: Dagger 基礎知識),致使社區中出現許多爭論,最終形成了不一樣開發者在 Android 應用中使用和配置 Dagger 的方式不一致。app

您可能會存在異議,認爲遷移到 Hilt 是不值得的,由於當前的 Dagger 配置已經很是完善,而且您徹底掌握 Dagger 的工做原理以及全部依賴項是如何被注入的。這對您我的來講多是正確的,可是您是否考慮過團隊的其餘成員 (包括潛在的將來同事)?您是否能確保切換至新項目時仍能正常運做?瞭解 Dagger 在應用中的配置和使用是一項艱鉅且耗時的工做。ide

經過在應用中使用 Hilt,上述工做量將會顯著減小,由於全部 Hilt 應用都使用相同的配置。新加入團隊的開發者不會對 Hilt 的配置感到困惑,由於這和他們以前的配置方式幾乎相同。性能

✅ 支持自定義組件

除了已經定義的標準組件以外,Hilt 也提供了建立自定義組件並添加到組件層次結構中的方法,詳見文章 Hilt — 添加組件到層次結構測試

雖然自定義組件下降了一致性,可是這會給您帶來很大收益!自定義組件也能夠配合模塊自動發現功能 (@InstallIn 註解功能) 以及測試替換功能一塊兒使用。ui

可是,自定義組件和 Hilt 內置組件的區別在於,這些組件沒法自動注入到 Android Framework 的類中 (即 @AndroidEntryPoint 的功能)。

✅ 支持 Dagger 和 Hilt 交互

Hilt 和 Dagger 能夠共存!若是容許 Hilt 接管 SingletonComponent,則能夠在應用中某些部分使用 Hilt 的特性,並從中受益,而其餘特殊部分仍保留 Dagger。這一樣意味着能夠 逐步完成向 Hilt 的遷移

❌ 不支持組件依賴

Hilt 的易用意味着它代替您作出了一些決定。Hilt 在組件關係中採用了子組件模式,您能夠查看 相關文檔 瞭解這樣設計的緣由。若是您堅信您的應用更適合採用組件依賴,那麼 Hilt 就不是您應用的正確選擇。

在大多數項目中,將 Hilt 遷移到 Dagger 是值得的。Hilt 給您帶來的收益超出了更新所需付出的努力。咱們提供了不少資源來助力遷移,請參閱:

若是您有任何問題,或者您須要更多相關信息,請在文章下方留言反饋。

相關文章
相關標籤/搜索