一、Dagger2是什么?
Dagger是程序在編譯時(shí)進(jìn)行依賴注入的框架,原來(lái)是由Square公司維護(hù),現(xiàn)在由Google維護(hù)。我們可以把它當(dāng)做應(yīng)用中的一個(gè)模塊, 負(fù)責(zé)為其它模塊提供實(shí)例并且注入依賴關(guān)系。Dagger Leiva說(shuō),特別適合用在低端設(shè)備上,因?yàn)樗鼪](méi)有采取反射而使用了預(yù)編譯技術(shù),因?yàn)榛诜瓷涞腄I非常占用資源和耗時(shí)。Dagger或許不是最理想的依賴注入框架,它是最高效的。這里我們簡(jiǎn)單介紹一下Dagger。
二、使用Dagger2有什么好處?
我們?cè)赼ctivity中有可能會(huì)用到很多很多的類,這些類要在activity中進(jìn)行實(shí)例化,這樣就導(dǎo)致我們的activity非常依賴這么多的類,這樣的程序耦合非常嚴(yán)重,不便于維護(hù)和擴(kuò)展。Dagger就是用來(lái)創(chuàng)造這個(gè)容器,所有需要被依賴的對(duì)象在Dagger的容器中實(shí)例化,并通過(guò)Dagger注入到合適的地方,實(shí)現(xiàn)解耦,MVP框架就是為解耦而生,因此MVP和Dagger是絕配;
三、什么是依賴?
在介紹Dagger 之前,我們先說(shuō)一下什么依賴以及什么是依賴注入?在 Class A 中,有 Class B 的實(shí)例,則稱 Class A 對(duì) Class B 有一個(gè)依賴。例如下面類 Human 中用到一個(gè) Father 對(duì)象,我們就說(shuō)類 Human 對(duì)類 Father 有一個(gè)依賴,如下:
public class Human {
...
Father father;
...
public Human() {
father = new Father();
}
}
四、什么是依賴注入?
依賴注入就是非自己主動(dòng)初始化依賴,而通過(guò)外部來(lái)傳入依賴的方式,簡(jiǎn)單來(lái)說(shuō)就是不使用 new 來(lái)創(chuàng)建依賴對(duì)象。使用 Dagger2 創(chuàng)建依賴對(duì)象,我們就不用手動(dòng)初始化了。個(gè)人認(rèn)為 Dagger2 和 MVP 架構(gòu)是比較不錯(cuò)的搭配,Activity 依賴的 Presenter 可以使用該DI框架直接生成,實(shí)現(xiàn)解耦,簡(jiǎn)單的使用方式如下:
public class MainActivity extends BaseActivity {
@Inject
MainActivityPresenter presenter;
...
}
若您還是對(duì)依賴注入不了解,點(diǎn)擊我可以讓您了解更多
,dagger2中核心點(diǎn)就是java注解,點(diǎn)擊我可以了解更多java注解知識(shí)
五、什么是JSR-330?
為了最大程度的提高代碼的復(fù)用性、測(cè)試性和維護(hù)性,java的依賴注入為注入類中的使用定義了一整套注解(和接口)標(biāo)準(zhǔn)。Dagger1和Dagger2(還有Guice)都是基于這套標(biāo)準(zhǔn),給程序帶來(lái)了穩(wěn)定性和標(biāo)準(zhǔn)的依賴注入方法。
六、Dagger的發(fā)展歷程?
Dagger的發(fā)展歷程由Dagger1到Dagger2。下面簡(jiǎn)單介紹一下兩個(gè)版本的區(qū)別:
1. Dagger1
這個(gè)版本不是這篇文章的重點(diǎn),所以我只是簡(jiǎn)略地說(shuō)一下。不管怎樣,Dagger1還是做了很多的貢獻(xiàn),可以說(shuō)是如今Android上最流行的依賴注入框架。它是由Square公司受到Guice啟發(fā)創(chuàng)建的。
基本特點(diǎn):
多個(gè)注入點(diǎn):依賴,通過(guò)injected
多種綁定方法:依賴,通過(guò)provided
多個(gè)modules:實(shí)現(xiàn)某種功能的綁定集合
多個(gè)對(duì)象圖: 實(shí)現(xiàn)一個(gè)范圍的modules集合
Dagger1是在編譯的時(shí)候?qū)嵭薪壎ǎ贿^(guò)也用到了反射機(jī)制。但這個(gè)反射不是用來(lái)實(shí)例化對(duì)象的,而是用于圖的構(gòu)成。Dagger會(huì)在運(yùn)行的時(shí)候去檢測(cè)是否一切都正常工作,所以使用的時(shí)候會(huì)付出一些代價(jià):偶爾會(huì)無(wú)效和調(diào)試?yán)щy。
2. Dagger2
Dagger2是Dagger1的分支,由谷歌公司接手開(kāi)發(fā),目前的版本是2.0。Dagger2是受到AutoValue項(xiàng)目的啟發(fā)。 剛開(kāi)始,Dagger2解決問(wèn)題的基本思想是:利用生成和寫(xiě)的代碼混合達(dá)到看似所有的產(chǎn)生和提供依賴的代碼都是手寫(xiě)的樣子。
如果我們將Dagger2和1比較,他們兩個(gè)在很多方面都非常相似,但也有很重要的區(qū)別,如下:
再也沒(méi)有使用反射:圖的驗(yàn)證、配置和預(yù)先設(shè)置都在編譯的時(shí)候執(zhí)行。
容易調(diào)試和可跟蹤:完全具體地調(diào)用提供和創(chuàng)建的堆棧
更好的性能:谷歌聲稱他們提高了13%的處理性能
代碼混淆:使用派遣方法,就如同自己寫(xiě)的代碼一樣
當(dāng)然所有這些很棒的特點(diǎn)都需要付出一個(gè)代價(jià),那就是缺乏靈活性,例如:Dagger2沒(méi)用反射所以沒(méi)有動(dòng)態(tài)機(jī)制。
六、Dagger2的主要方法以及相關(guān)介紹?
Dagger2主要的注解有:@Inject、@Module 、@Component 、@Provides 、@Scope 、@SubComponent 等。
1. @Inject:
通常在需要依賴的地方使用這個(gè)注解。換句話說(shuō),你用它告訴Dagger這個(gè)類或者字段需要依賴注入。這樣,Dagger就會(huì)構(gòu)造一個(gè)這個(gè)類的實(shí)例并滿足他們的依賴。
2. @Module:
Modules類里面的方法專門(mén)提供依賴,所以我們定義一個(gè)類,用@Module注解,這樣Dagger在構(gòu)造類的實(shí)例的時(shí)候,就知道從哪里去找到需要的 依賴。modules的一個(gè)重要特征是它們?cè)O(shè)計(jì)為分區(qū)并組合在一起(比如說(shuō),在我們的app中可以有多個(gè)組成在一起的modules)。
3. @Provides:
在modules中,我們定義的方法是用這個(gè)注解,以此來(lái)告訴Dagger我們想要構(gòu)造對(duì)象并提供這些依賴。
4. @Component:
Components從根本上來(lái)說(shuō)就是一個(gè)注入器,也可以說(shuō)是@Inject和@Module的橋梁,它的主要作用就是連接這兩個(gè)部分。 Components可以提供所有定義了的類型的實(shí)例,比如:我們必須用@Component注解一個(gè)接口然后列出所有的 @Modules組成該組件,如 果缺失了任何一塊都會(huì)在編譯的時(shí)候報(bào)錯(cuò)。所有的組件都可以通過(guò)它的modules知道依賴的范圍。
Component會(huì)查找目標(biāo)類中用Inject注解標(biāo)注的屬性,查找到相應(yīng)的屬性后會(huì)接著查找該屬性對(duì)應(yīng)的用Inject標(biāo)注的構(gòu)造函數(shù)(這時(shí)候就發(fā)生聯(lián)系了),剩下的工作就是初始化該屬性的實(shí)例并把實(shí)例進(jìn)行賦值。因此我們也可以給Component叫另外一個(gè)名字注入器(Injector)
Module應(yīng)該是屬于Component的實(shí)例端的(連接各種目標(biāo)類依賴實(shí)例的端),Component的新職責(zé)就是管理好Module,Component中的modules屬性可以把Module加入Component,modules可以加入多個(gè)Module。
5. @Scope:
Scopes可是非常的有用,Dagger2可以通過(guò)自定義注解限定注解作用域。后面會(huì)演示一個(gè)例子,這是一個(gè)非常強(qiáng)大的特點(diǎn),因?yàn)榫腿缜懊嬲f(shuō)的一樣,沒(méi)必要讓每個(gè)對(duì)象都去了解如何管理他們的實(shí)例。
七、Dagger2的使用詳解?
1. 添加依賴
android-apt, 提供dagger2使用編譯生成類的功能。具體作用請(qǐng)看http://blog.csdn.net/zjbpku/article/details/22976291。
retrolambda, 提供Lambda表達(dá)式支持的功能。
apply plugin: 'com.android.application'
apply plugin: 'com.neenbedankt.android-apt'//添加這里
android {
...
// 使用Java1.8
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8//添加這里
//targetCompatibility JavaVersion.VERSION_1_8
}
}
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'//添加這里
}
}
dependencies {
compile 'com.google.dagger:dagger:2.9'//添加這里
apt 'com.google.dagger:dagger-compiler:2.9'//添加這里
...
}
由于工作關(guān)系這里Dagger2上篇先寫(xiě)到這里,后續(xù)繼續(xù)補(bǔ)充下篇詳解。