Android註解三大框架Dagger、Hilt 和 Koin 有何不同?
Dagger 和 Koin 無疑是 Android 中最流行的兩個依賴注入框架。這兩個庫具有相同的用途,而且看起來非常相似,但它們在底層的工作方式卻非常不同。
那麼Hilt
是什麼呢?Hilt
是一個內部使用Dagger
的庫,只是簡化了它的用法,因此我在這裡所說的有關Dagger
的內容也適用於 Hilt。在本文中,我不會告訴您應該選擇哪個庫。相反,我想向您展示它們的本質區別以及這些差異對您的應用造成的影響。
Dagger
如果我們希望 Dagger 提供某個類的例項,我們要做的就是在建構函式中新增@Inject
註解。
新增這個註解後,Dagger
會在構建時為這個類生成一個Factory
。在該用例下,由於它的類名是CompositeAdapter
CompositeAdapter**_**Factory
的類。
此類包含建立CompositeAdapter
類的例項所需的所有資訊。
如你所看到該工廠類實現了get()
並返回了一個新的CompositeAdapter
例項。這實際上是此類實現的Provider <T>
介面中指定的方法。其他類可以使用Provider<T>
介面來獲取一個類的例項。
如果我們用 Hilt 代替 Dagger 呢?
在這個例子中,沒有任何區別。Hilt
是一個內部使用Dagger
的庫,我向你展示的類是由Dagger
生成的。如果您使用Hilt
,它確實為我們生成了一些額外的類,這些類簡化了Dagger
Koin
Koin
與Dagger
以及Hilt
相比,管理依賴項的方法完全不同。要在 Koin 中註冊依賴項,我們不會使用任何註解,因為Koin不會生成任何程式碼。相反,我們必須為模組提供工廠,這些模組將用於建立專案中所需的每個類的例項。
Koin
將這些工廠類的引用新增到InstancesRegistry
類中,該類包含對我們編寫的所有工廠的引用。
該map
中的key
是類的全名或使用命名引數時提供的名稱。對應的值是我們編寫的工廠,將用於建立類的例項。
要獲得依賴關係,我們需要呼叫get()
(比如在一個工廠類中) 或者通過在activities
fragments
中呼叫inject()
委託屬性 ,從而懶載入get()
。get()
方法將查詢為給定型別的類註冊工廠,並將其注入其中。
有什麼影響?
Dagger 生成程式碼來提供依賴,而 Koin 不生成程式碼,這實際上帶來了一些影響。
1. 錯誤處理
因為Dagger
是一個編譯時依賴注入框架,如果我們忘記提供某些依賴,我們幾乎會立即知道我們的錯誤,因為我們的專案將構建失敗。
例如,如果我們忘記向建構函式的CompositeAdapter
中新增@Inject
註解,並嘗試將其注入 fragment 中,則構建將失敗,並顯示適當的錯誤,確切地告訴我們出了什麼問題。
在 Koin 中的情況有所不同,因為它不會生成任何程式碼。如果我們忘記為CompositeAdapter
類添加工廠,應用將會成功構建,但是會丟擲RuntimeException
一旦我們請求獲取這個類的例項。它可能會在應用啟動時發生,因此我們可能會立即注意到它,但也可能稍後在其他螢幕上或當用戶執行某些特定操作時發生。
2. 對構建時間的影響
Koin 不生成任何程式碼的優點是:它對我們的構建時間的影響要小得多。Dagger
需要使用註解處理器來掃描程式碼並生成適當的類。這可能需要一些時間,可能會減慢我們的構建。
3. 對執行時效能的影響
從另一方面來說,因為 Koin 在執行時解析依賴項,所以它的執行時效能稍差一些。
到底相差多少呢?
為了估算效能差異我們可以使用該庫,其中Rafa Vázquez
基於不同的裝置上測量並比較了這兩個庫。測試資料的編寫方式可以模擬多個級別的傳遞依賴關係,因此它不僅僅是具有 4 個類的虛擬應用程式。
如您所見,Dagger
對啟動效能幾乎沒有影響。另一方面,在Koin
中,我們可以看到它花費了很多時間。在Dagger
中注入依賴也比在Koin
中快一些。
總結
正如我在本文開始時所說的,我這裡的目標不是告訴您要使用哪個庫。我在兩個不同的大專案中都使用了Koin
和Dagger
。老實說,我認為選擇Dagger
還是Koin
並不重要,重要的是能夠讓你編寫乾淨、簡單且易於單元測試的程式碼。我認為所有的庫:Koin,Dagger 和 Hilt 都達到了這個目的。
所有這些庫都有自己的優勢,我希望瞭解它們在底層是如何工作的,能夠幫助您自己決定哪種庫最適合您的應用。
Android高階開發系統進階筆記、最新面試複習筆記PDF,我的GitHub
文末
您的點贊收藏就是對我最大的鼓勵!
歡迎關注我,分享Android乾貨,交流Android技術。
對文章有何見解,或者有何技術問題,歡迎在評論區一起留言討論!