依賴注入框架 Hilt 的使用

Hilt

這篇記錄下 Hilt 最基本的使用方法。

Hilt 是基于 Dagger 開發(fā)的依賴注入框架。我們知道 Dagger 是 Java 開發(fā)中無可否認(rèn)的功能最為強(qiáng)大的依賴注入框架罐盔,但是它的缺點(diǎn)是使用起來比較復(fù)雜汰寓,尤其是對(duì)于初學(xué)者而言芍锦,學(xué)習(xí)曲線異常陡峭斤儿。而依賴注入框架在 Android 開發(fā)中也是一個(gè)非常重要的工具,因此驳癌,在 Kotlin 成為了 Android 開發(fā)者的首選語言之后,開源社區(qū)中誕生了許多基于 Kotlin 依賴注入框架役听,比如 KoinKodein颓鲜。谷歌當(dāng)然也注意到了這一點(diǎn),所以也基于 Dagger 推出了更簡單易上手的 Hilt典予,它的主要優(yōu)勢(shì)是:

  • 基于 Android 簡化了 Dagger 相關(guān)的基礎(chǔ)架構(gòu)甜滨;
  • 提供了一組標(biāo)準(zhǔn)的 Component 和 Scope 以簡化使用、提升可讀性以及便于代碼共享瘤袖;
  • 簡化針對(duì)不同的構(gòu)建類型(比如測(cè)試衣摩、調(diào)試或發(fā)布類型)配置不同的綁定。

之所以能做到以上這幾點(diǎn)捂敌,是因?yàn)?Hilt 自動(dòng)幫我們做了很多工作艾扮,比如自動(dòng)生成用于和 Android Framwork 綁定的 Component/Scoped annotations/Bindings/Qualifier 等,而如果使用 Dagger 的話占婉,這些都是需要我們自己手動(dòng)編寫代碼來管理的泡嘴。

Hilt 的基本使用

使用方式上,Hilt 和 Dagger 相比最明顯的區(qū)別是逆济,不再需要定義 Component酌予,對(duì)于每一個(gè) Android 基礎(chǔ)類,Hilt 會(huì)自動(dòng)為它生成對(duì)應(yīng)的 Component奖慌,并且會(huì)根據(jù)安卓組件的生命周期來創(chuàng)建和銷毀抛虫。如下:

Hilt 組件 注入器面向的對(duì)象
ApplicationComponent Application
ActivityRetainedComponent ViewModel
ActivityComponent Activity
FragmentComponent Fragment
ViewComponent View
ViewWithFragmentComponent 帶有 @WithFragmentBindings 注釋的 View
ServiceComponent Service

因此,對(duì)于一個(gè)最簡單的 MVVM 項(xiàng)目而言简僧,使用 Hilt 做依賴注入一般需要按照以下的步驟:

  • 添加 Hilt 插件和依賴建椰,對(duì)于每個(gè) module 都要單獨(dú)添加
  • 使用 @HiltAndroidApp 標(biāo)注你自定義的 Application
  • 使用 @AndroidEntryPoint 標(biāo)注你的 Fragment 或者 Activity
  • 使用 @HiltViewModel 標(biāo)注你的 ViewModel 類,以及用 @Inject 標(biāo)注構(gòu)造器
  • 使用 @Inject 標(biāo)注需要注入的依賴涎劈,比如 Repository 等
  • 定義 Hilt 模塊广凸,用于提供無法直接注入的依賴,比如接口類和外部的依賴類等
    • 使用 @InstallIn 標(biāo)注該模塊的作用范圍
    • 使用 @Provides 標(biāo)注提供每個(gè)依賴的方法
    • 使用 @Binds 標(biāo)注需要注入依賴的接口和具體實(shí)現(xiàn)(通過抽象類和抽象方法)

具體例子可以參考我的開源小項(xiàng)目:Jithub

模塊和組件

雖然 Hilt 大大簡化了依賴注入的使用蛛枚,但是使用方式上和 Dagger 并沒有太大區(qū)別谅海,最基礎(chǔ)的組成部分依舊是模塊和組件。對(duì)于某個(gè) Hilt 模塊蹦浦,如果我們想要注入多個(gè)相同類型的依賴扭吁,同樣需要通過定義限定符來實(shí)現(xiàn)。

使用注解定義限定符(例子來自官方文檔):

@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class AuthInterceptorOkHttpClient

@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class OtherInterceptorOkHttpClient

除此之外,我們還可以使用 Hilt 自帶的限定符侥袜,比如 @ActivityContext@ApplicationContext 等蝌诡。

組件的使用細(xì)節(jié)

之前提到過對(duì)于不同的 Android 類,Hilt 會(huì)為之生成對(duì)應(yīng)的組件枫吧,我們?cè)谀K中通過 @InstalledIn 引用組件浦旱,然后 Hilt 會(huì)將模塊安裝到對(duì)應(yīng)的組件中,最后再把依賴注入到組件中九杂。

除此之外颁湖,每個(gè)組件都有自己的生命周期,而且我們還可以為組件限定作用域例隆。不同的組件作用域內(nèi)可使用的依賴也不同甥捺,比如 @FragmentScoped 作用域內(nèi)的依賴可以在 @ActivityScoped 的組件中使用,但是無法在 @ViewScoped 的組件中使用镀层。

Android 類 生成的組件 作用域
Application ApplicationComponent @Singleton
View Model ActivityRetainedComponent @ActivityRetainedScope
Activity ActivityComponent @ActivityScoped
Fragment FragmentComponent @FragmentScoped
View ViewComponent @ViewScoped
帶有 @WithFragmentBindings 注釋的 View ViewWithFragmentComponent @ViewScoped
Service ServiceComponent @ServiceScoped

其它細(xì)節(jié)

如果需要在 Hilt 不支持的類中注入依賴镰禾,比如 ContentProvider,我們可以通過創(chuàng)建 EntryPoint 來訪問這些依賴唱逢。

通過 @EntryPoint 創(chuàng)建依賴入口(通常是一個(gè)接口)吴侦,然后在其中定義方法提供所需要的依賴,再通過 @InstalledIn 來定義安裝到哪個(gè)組件惶我。另外妈倔,訪問 EntryPoint 依賴也和普通的依賴不同,我們需要通過之前定義好的 EntryPoint 接口來訪問依賴項(xiàng)绸贡。

val entryPointInterface = EntryPointAccessors.fromXxx(Application/Activity/Fragment/Context, EntryPointInterface::class.java)

EntryPointAccessors 中包含不同的創(chuàng)建方法盯蝴,對(duì)應(yīng)于創(chuàng)建不同的組件,比如 EntryPointAccessors.fromApplication() 對(duì)應(yīng)于 SingletonComponent听怕,fromActivity() 對(duì)應(yīng)于 ActivityComponent 等捧挺。創(chuàng)建 EntryPoint 接口對(duì)象之后,我們就可以通過它來訪問依賴了尿瞭。

小結(jié)

可以看到闽烙,Hilt 大大簡化了傳統(tǒng)依賴注入框架的使用方式,但是核心功能基本和 Dagger 保持一致声搁,因此黑竞,開發(fā)人員可以將更多的注意力放在開發(fā)上,從而提升開發(fā)效率疏旨。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末很魂,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子檐涝,更是在濱河造成了極大的恐慌遏匆,老刑警劉巖法挨,帶你破解...
    沈念sama閱讀 219,188評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異幅聘,居然都是意外死亡凡纳,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門帝蒿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來荐糜,“玉大人,你說我怎么就攤上這事葛超∧” “怎么了?”我有些...
    開封第一講書人閱讀 165,562評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵巩掺,是天一觀的道長。 經(jīng)常有香客問我页畦,道長胖替,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,893評(píng)論 1 295
  • 正文 為了忘掉前任豫缨,我火速辦了婚禮独令,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘好芭。我一直安慰自己燃箭,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評(píng)論 6 392
  • 文/花漫 我一把揭開白布舍败。 她就那樣靜靜地躺著招狸,像睡著了一般。 火紅的嫁衣襯著肌膚如雪邻薯。 梳的紋絲不亂的頭發(fā)上裙戏,一...
    開封第一講書人閱讀 51,708評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音厕诡,去河邊找鬼累榜。 笑死,一個(gè)胖子當(dāng)著我的面吹牛灵嫌,可吹牛的內(nèi)容都是我干的壹罚。 我是一名探鬼主播,決...
    沈念sama閱讀 40,430評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼寿羞,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼猖凛!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起稠曼,我...
    開封第一講書人閱讀 39,342評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤形病,失蹤者是張志新(化名)和其女友劉穎客年,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體漠吻,經(jīng)...
    沈念sama閱讀 45,801評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡量瓜,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了途乃。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片绍傲。...
    茶點(diǎn)故事閱讀 40,115評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖耍共,靈堂內(nèi)的尸體忽然破棺而出烫饼,到底是詐尸還是另有隱情,我是刑警寧澤试读,帶...
    沈念sama閱讀 35,804評(píng)論 5 346
  • 正文 年R本政府宣布杠纵,位于F島的核電站,受9級(jí)特大地震影響钩骇,放射性物質(zhì)發(fā)生泄漏比藻。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評(píng)論 3 331
  • 文/蒙蒙 一倘屹、第九天 我趴在偏房一處隱蔽的房頂上張望银亲。 院中可真熱鬧,春花似錦纽匙、人聲如沸务蝠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽馏段。三九已至,卻和暖如春力穗,著一層夾襖步出監(jiān)牢的瞬間毅弧,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評(píng)論 1 272
  • 我被黑心中介騙來泰國打工当窗, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留够坐,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,365評(píng)論 3 373
  • 正文 我出身青樓崖面,卻偏偏與公主長得像元咙,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子巫员,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容