Android開(kāi)發(fā)-Dagger2學(xué)習(xí)記錄

前言

Dagger2是目前Android流行的框架搭配之一俐芯。所以棵介,學(xué)起來(lái)!(P.s:看了好多好多的文章解讀~)

原理解讀

Dagger2是什么泼各?

官方介紹:

A fast dependency injector for Java and Android.

譯:Java和Android的快速依賴關(guān)系注入器鞍时。

個(gè)人理解:Dagger就是用來(lái)創(chuàng)造出一個(gè)容器,所有需要被依賴的對(duì)象在Dagger的容器中實(shí)例化扣蜻,并通過(guò)

? Dagger注入到合適的地方,實(shí)現(xiàn)解耦及塘。

什么是依賴注入莽使?

依賴注入,英文名Dependency Injection笙僚,簡(jiǎn)稱(chēng)DI芳肌。簡(jiǎn)單說(shuō)就是目標(biāo)類(lèi)(目標(biāo)類(lèi)需要進(jìn)行依賴初始化的類(lèi))中所依賴的其他的類(lèi)的初始化過(guò)程,不是通過(guò)手動(dòng)編碼的方式創(chuàng)建,而是通過(guò)技術(shù)手段可以把其他的類(lèi)的已經(jīng)初始化好的實(shí)例自動(dòng)注入到目標(biāo)類(lèi)中亿笤。(P.s:不明白沒(méi)關(guān)系翎迁,看文章你就明白了!認(rèn)真臉>谎Α)

優(yōu)點(diǎn)

  • 增加開(kāi)發(fā)效率汪榔,神曲重復(fù)的簡(jiǎn)單體力勞動(dòng)
  • 更好的管理類(lèi)實(shí)例
  • 解耦
  • 便于擴(kuò)展和維護(hù)

缺點(diǎn)

  • 相對(duì)于其他框架,有一定學(xué)習(xí)成本肃拜,需要時(shí)間消化痴腌。我自己就看了好多好多文章。燃领。士聪。。

少?gòu)U話猛蔽!入正題剥悟!

Dagger2提供的注解:@Inject@Component@Module曼库、@Provieds

在描述第一組注解的作用前区岗,我們來(lái)看一則例子:

? 假設(shè)領(lǐng)導(dǎo)下午要出去視察民情,需要一輛公交車(chē)凉泄,司機(jī)就不用請(qǐng)了躏尉,領(lǐng)導(dǎo)做表率自己開(kāi),小秘把領(lǐng)導(dǎo)的指示告訴了車(chē)場(chǎng)調(diào)度員后众。
??找輛公交車(chē)要停放在停車(chē)場(chǎng)(Bus要注入到ParkingActivity)胀糜,停車(chē)場(chǎng)不管公交車(chē)按什么路線停車(chē)(ParkingActivity不管Bus是如何注入的),車(chē)場(chǎng)調(diào)度員會(huì)負(fù)責(zé)好管理(Dagger2容器會(huì)將Bus的注入到ParkingActivity)蒂誉。

public class Bus {
@Inject
public Bus() {
}
}

public class ParkingActivity extends Activity {
@Inject
Bus mBus;
@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_dagger);
  DaggerParkingComponent.create().inject(this);//DaggerParkingComponent類(lèi)需要編譯才會(huì)生成
  ((TextView) findViewById(R.id.text)).setText(mBus.toString());
}
}

@Component
public interface ParkingComponent {
void inject(ParkingActivity activity);
}

DaggerParkingComponent類(lèi)是編譯過(guò)后Dagger2自動(dòng)生成的教藻,是ParkingComponent的實(shí)現(xiàn)類(lèi),可以說(shuō)DaggerParkingComponent就是實(shí)際的車(chē)場(chǎng)調(diào)度員右锨,ParkingComponent是對(duì)車(chē)場(chǎng)調(diào)度員的約束括堤,在onCreate方法完成了注入過(guò)程。

@Inject的作用

(1)注解在屬性中表示該屬性需要依賴注入绍移,不能使用private修飾悄窃,示例代碼表示需要注入屬性

? mBus(Bus的車(chē)位):

@Inject
Bus mBus;

(2)注解在方法中表示該方法需要依賴注入,不能是抽象方法蹂窖,不能使用private修飾轧抗,示例代碼表示

? 需要注入方法injectBus:

//@Inject
Bus mBus;
@Inject
public void injectBus(Bus bus) {
mBus = bus;
}

? 方法注入的參數(shù)同樣由Dagger2容器提供,以上代碼的目的與第一點(diǎn)介紹的屬性注入一樣瞬测,都是為

了注入mBus横媚,如果目的是注入屬性的話纠炮,方法注入和屬性注入基本沒(méi)有區(qū)別,屬性注入是Dagger2中使用最多的一個(gè)注入方式灯蝴。
??那么什么情況下應(yīng)該使用方法注入恢口?比如依賴需要this對(duì)象的時(shí)候,方法注入可以提供安全的this對(duì)象穷躁。
??注意耕肩,Dagger2容器先調(diào)用屬性注入,然后再方法注入折砸,若把示例代碼mBus@Inject取消注釋?zhuān)藭r(shí)mBus會(huì)注入2次看疗,并且兩次注入的Bus也不相同。

(3)注解在構(gòu)造方法中表示此類(lèi)能為Dagger2提供依賴關(guān)系睦授,Dagger2可以使用這個(gè)構(gòu)造方法構(gòu)建對(duì)象(Bus的來(lái)歷):

@Inject
public Bus() {
}

? 如果有多個(gè)構(gòu)造函數(shù)两芳,只能注解一個(gè),否則編譯報(bào)錯(cuò)去枷。

@Component的作用

一般用來(lái)注解接口怖辆,被注解的接口在編譯時(shí)會(huì)生成相應(yīng)的實(shí)例。實(shí)例名稱(chēng)一般以Dagger為前綴删顶,作為所需注入依賴(ParkingActivity的mBus屬性)和提供依賴(Bus類(lèi)構(gòu)造方法)之間的橋梁竖螃,把提供的依賴)注入到所需注入的依賴中(ParkingActivity的mBus屬性)。

例子一總結(jié):通俗說(shuō)逗余,就是Dagger2的容器特咆,在例子中是車(chē)場(chǎng)調(diào)度員,把公交車(chē)和停車(chē)場(chǎng)聯(lián)系在一起录粱。車(chē)場(chǎng)調(diào)度員知道停車(chē)場(chǎng)要準(zhǔn)備一輛公交車(chē)腻格,停車(chē)場(chǎng)不需要知道車(chē)是哪里來(lái)的,也不需要知道怎么停啥繁,車(chē)場(chǎng)調(diào)度員找好車(chē)后菜职,停在車(chē)位上就完事嗦哆,等候領(lǐng)導(dǎo)用車(chē)就可以了低矮。

兩個(gè)@Inject注解形成了依賴關(guān)系,@Component作為連接這個(gè)關(guān)系的橋梁存在碉纳,尋找到依賴并且注入适室,并且注入與被注入之間互不干涉嫡意,經(jīng)過(guò)編譯@Component生成Dagger為前綴的實(shí)例,調(diào)用實(shí)例的方法捣辆。

第二組注解例子:

領(lǐng)導(dǎo)想著不妥鹅很,自己沒(méi)開(kāi)過(guò)公交車(chē),為保險(xiǎn)起見(jiàn)還是趕緊吩咐小秘罪帖,去給配個(gè)公交車(chē)司機(jī)促煮,小秘自然跟車(chē)場(chǎng)調(diào)度員說(shuō)了。
??車(chē)場(chǎng)調(diào)度員一想整袁,只是比之前多了一個(gè)步驟菠齿,給公交車(chē)配置一個(gè)司機(jī)(Bus類(lèi)添加String類(lèi)型Driver構(gòu)造方法)。于是打電話給開(kāi)公交車(chē)的隔壁老王坐昙,老王自然是應(yīng)諾了下來(lái)绳匀,于是乎,對(duì)例子一的代碼做一下修改炸客。

public class Bus {
   private String driver;
   @Inject
   public Bus(String driver) {
       this.driver = driver;
   }
}

public class ParkingActivity extends Activity {
   @Inject
   Bus mBus;
   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_dagger);
       DaggerParkingComponent.create().inject(this);//DaggerParkingComponent類(lèi)需要編譯才會(huì)生成
       ((TextView) findViewById(R.id.text)).setText(mBus.toString());//重寫(xiě)B(tài)us的toString()方法能看到打印出"隔壁老王"疾棵,注入成功
   }
}

@Component(modules = ParkingModule.class)
public interface ParkingComponent {
   void inject(ParkingActivity activity);
}

@Module
public class ParkingModule {
   public ParkingModule() {
   }
   @Provides
   public String provideDriver() {
       return "隔壁老王";
   }
}
@Module的作用

該注解與@Provides結(jié)合為Dagger2提供依賴關(guān)系,對(duì)上文@Inject第三點(diǎn)的補(bǔ)充痹仙,用于不能用@Inject提供依賴的地方是尔,如第三方庫(kù)提供的類(lèi),基本數(shù)據(jù)類(lèi)型等不能修改源碼的情況开仰。

@Provieds的作用

@Provides僅能注解方法拟枚,且方法所在類(lèi)要有@Module注解。注解后的方法表示Dagger2能用該方法實(shí)例對(duì)象提供依賴众弓。按照慣例恩溅,@Provides方法的命名以provide為前綴,方便閱讀管理谓娃。

例子二總結(jié):首先@Component注解包含了一個(gè)ParkingModule類(lèi)脚乡,表示Dagger2可以從ParkingModule類(lèi)查找依賴,Dagger2會(huì)自動(dòng)查找ParkingModule類(lèi)有@Provides注釋的方法實(shí)例依賴滨达,最后完成注入奶稠。
注意1,如果在ParkingModule里面同樣提供Bus的依賴弦悉,Dagger2會(huì)優(yōu)先在@Module注解的類(lèi)上查找依賴窒典,沒(méi)有的情況才會(huì)去查詢類(lèi)的@Inject構(gòu)造方法,如下面的代碼稽莉,則Bus的司機(jī)就是小王而不是老王了瀑志。

@Module
public class ParkingModule {
   public ParkingModule() {
   }
   @Provides
   public String provideDriver() {
       return "隔壁老王";
   }
   @Provides
   public Bus provideBus() {
       return new Bus("樓上小王");
   }
}

注意2@Module類(lèi)可以從構(gòu)造方法傳入依賴污秆,@Provides方法也可以有依賴關(guān)系劈猪。
@Provides方法也有依賴關(guān)系的情況,Dagger2會(huì)繼續(xù)查找可以提供依賴的方法良拼,類(lèi)似于一種遞歸的狀態(tài)战得,一步一步返回實(shí)例。如下代碼庸推,ParkingModule構(gòu)造方法傳入driverprovideDriver方法提供依賴返回常侦,provideDriver返回driver作為provideBus方法的依賴實(shí)例Bus浇冰。
ParkingModule加入有參構(gòu)造方法后,調(diào)用方式也需要變成聋亡,現(xiàn)在司機(jī)就變成了樓下老李了肘习。

@Module
public class ParkingModule {
   private String driver;
   public ParkingModule(String driver) {
       this.driver = driver;
   }
   @Provides
   public String provideDriver() {
       return driver;
   }
   @Provides
   public Bus provideBus(String driver) {
       return new Bus(driver);
   }
}
   //調(diào)用方式改變
   DaggerParkingComponent.builder().parkingModule(new ParkingModule("樓下老李")).build().inject(this);

總結(jié)

最后,來(lái)總結(jié)下依賴注入的大致流程:

1:查找Module中是否有該實(shí)例的@Provides方法坡倔。

  • 1.1:有漂佩,走第2點(diǎn)。

  • 1.2:沒(méi)有罪塔,查找該實(shí)例是否有@Inject構(gòu)造方法投蝉。

??????1.2.1:有,走第3點(diǎn)征堪。

??????1.2.2:沒(méi)有瘩缆,注入失敗。

2:@Provides方法是否有參數(shù)

  • 2.1:有请契,則回到第1點(diǎn)查找每個(gè)參數(shù)的依賴
  • 2.2:沒(méi)有咳榜,實(shí)例該類(lèi)返回一次依賴

3:@Inject構(gòu)造方法是否有參數(shù)

  • 3.1:有,則回到第1點(diǎn)查找每個(gè)參數(shù)的依賴
  • 3.2:沒(méi)有爽锥,實(shí)例該類(lèi)返回一次依賴

4:以上流程遞歸返回注入目標(biāo)的所有依賴涌韩,最后依賴注入。

參考鏈接

dagger2讓你愛(ài)不釋手-基礎(chǔ)依賴注入框架篇

google四件套之Dagger2氯夷。從入門(mén)到愛(ài)不釋手系列

Android Dagger2 從零單排系列

Dagger2使用

Dagger2簡(jiǎn)單入門(mén)

淺析Dagger2的使用

Android_Dagger2篇——從小白最易上手的角度 + 最新dagger.android

Dagger2 最清晰的使用教程

dagger2到底有哪些好處

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末臣樱,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子腮考,更是在濱河造成了極大的恐慌雇毫,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,185評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件踩蔚,死亡現(xiàn)場(chǎng)離奇詭異棚放,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)馅闽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門(mén)飘蚯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人福也,你說(shuō)我怎么就攤上這事局骤。” “怎么了暴凑?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,524評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵峦甩,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我现喳,道長(zhǎng)凯傲,這世上最難降的妖魔是什么犬辰? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,339評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮泣洞,結(jié)果婚禮上忧风,老公的妹妹穿的比我還像新娘。我一直安慰自己球凰,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評(píng)論 6 391
  • 文/花漫 我一把揭開(kāi)白布腿宰。 她就那樣靜靜地躺著呕诉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪吃度。 梳的紋絲不亂的頭發(fā)上甩挫,一...
    開(kāi)封第一講書(shū)人閱讀 51,287評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音椿每,去河邊找鬼伊者。 笑死,一個(gè)胖子當(dāng)著我的面吹牛间护,可吹牛的內(nèi)容都是我干的亦渗。 我是一名探鬼主播,決...
    沈念sama閱讀 40,130評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼汁尺,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼法精!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起痴突,我...
    開(kāi)封第一講書(shū)人閱讀 38,985評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤搂蜓,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后辽装,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體帮碰,經(jīng)...
    沈念sama閱讀 45,420評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評(píng)論 3 334
  • 正文 我和宋清朗相戀三年拾积,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了殉挽。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,779評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡殷勘,死狀恐怖此再,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情玲销,我是刑警寧澤输拇,帶...
    沈念sama閱讀 35,477評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站贤斜,受9級(jí)特大地震影響策吠,放射性物質(zhì)發(fā)生泄漏逛裤。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評(píng)論 3 328
  • 文/蒙蒙 一猴抹、第九天 我趴在偏房一處隱蔽的房頂上張望带族。 院中可真熱鬧,春花似錦蟀给、人聲如沸蝙砌。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,716評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)择克。三九已至,卻和暖如春前普,著一層夾襖步出監(jiān)牢的瞬間肚邢,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,857評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工拭卿, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留骡湖,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,876評(píng)論 2 370
  • 正文 我出身青樓峻厚,卻偏偏與公主長(zhǎng)得像响蕴,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子目木,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評(píng)論 2 354

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