本文更新于2017年11月15日
閱讀本文大概需要三分半焰络。
前言
dagger
出來已經(jīng)很長(zhǎng)時(shí)間了,技術(shù)的更新日新月異》龋現(xiàn)在網(wǎng)上關(guān)于dagger2
的搜索記錄大部分還是16年及以前的舔琅。想著應(yīng)該出一篇文章對(duì)一些好博客的精神做個(gè)總結(jié),再就是更新洲劣。讓現(xiàn)在要使用dagger2
的朋友更簡(jiǎn)單的就能操作dagger2
并理解它。
如果您對(duì)dagger2的概念课蔬,整個(gè)依賴注入框架還不清楚囱稽,可以先了解下系列文章:
Android:dagger2讓你愛不釋手-基礎(chǔ)依賴注入框架篇
Android:dagger2讓你愛不釋手-重點(diǎn)概念講解、融合篇
Android:dagger2讓你愛不釋手-終結(jié)篇
這三篇系列文章是全網(wǎng)知識(shí)點(diǎn)講解的幾乎最易懂明了的文章二跋。
可以先看理論战惊,再讀本文實(shí)踐印證≡矗或者先讀本文實(shí)踐得到預(yù)期結(jié)果吞获,再補(bǔ)系列理論。
文章的最后谚鄙,提供了demo源碼各拷。 (不知道有沒有讀者看文章和我一樣,不管什么長(zhǎng)篇大論闷营,先滑到最底烤黍,看文章多長(zhǎng)知市,有沒有提供demo。沒有的話速蕊,掃幾眼嫂丙,如果寫的不好更要關(guān)掉去看別的文章)
目錄
正文內(nèi)容分為以下三個(gè)部分:
dagger框架出處及現(xiàn)在版本
從零開始按部就班配置及使用dagger2并過程內(nèi)講解主要知識(shí)點(diǎn)
梳理思路,概括性講述注入流程
盡量廢話少說规哲,簡(jiǎn)明扼要
Now,start!!!
dagger框架出處及現(xiàn)在版本
Dagger2是Dagger的升級(jí)版跟啤,是一個(gè)依賴注入框架,現(xiàn)在由Google接手維護(hù)唉锌。截止寫文目前隅肥,已經(jīng)發(fā)布2.13版本。dagger2框架源碼地址
從零開始按部就班配置及使用dagger2并過程內(nèi)講解主要知識(shí)點(diǎn)
- 添加依賴糊秆,只在module的gradle文件里導(dǎo)入即可武福,不再需要apt
compile 'com.google.dagger:dagger:2.13'
annotationProcessor 'com.google.dagger:dagger-compiler:2.13'
舉個(gè)例子:
內(nèi)容是通過向MainActivity注入一個(gè)Presenter,然后通過Presenter來設(shè)置TextView顯示內(nèi)容為user實(shí)體對(duì)象的屬性name
其中User實(shí)體類的代碼如下:
public class User {
public String name;
public User(String name) {
this.name = name;
}
}
MainPresenter的代碼:
public class MainPresenter {
MainActivity activity;
User user;
public MainPresenter(MainActivity activity, User user) {
this.user = user;
this.activity = activity;
}
public void showUserName() {
activity.showUserName(user.name);
}
}
都比較簡(jiǎn)單痘番。
我們按編程操作思路來使用dagger捉片,分為五步
-
首先我們?cè)贛ainActivity里注入(Inject) MainPresenter (第一步)
public class MainActivity extends AppCompatActivity { @Inject MainPresenter mainPresenter; ... @Override protected void onCreate(Bundle savedInstanceState) { ... } }
注入之后呢,MainActivity會(huì)持有MainPresenter 的引用汞舱。MainPresenter被依賴伍纫,那么肯定會(huì)有new的過程,MainPresenter的構(gòu)造方法有參數(shù)昂芜,怎么傳參莹规?誰傳過去?這時(shí)泌神,Module
這個(gè)使者就出現(xiàn)了良漱。
-
編寫module,為注入時(shí)的實(shí)例化提供所需的參數(shù) (第二步)
@Module public class MainModule { private MainActivity mainActivity; public MainModule(MainActivity activity){ mainActivity = activity;} @Provides public MainActivity providesActivity(){ return mainActivity; } @Provides public User providesUser(){return new User("the user from MainModule"); } @Provides public MainPresenter providesMainPresenter(MainActivity activity,User user){ return new MainPresenter(activity,user); } }
首先我們需要明確一點(diǎn)欢际,就是
Module的作用是用來提供生成依賴對(duì)象的
比如我要注入MainPresenter母市,那么這個(gè)Module的作用就是需要生成一個(gè)MainPresenter的對(duì)象,來讓Dagger2注入到MainActivity中损趋。
所以我們這里需要編寫一個(gè)函數(shù)providesMainPresenter
,這個(gè)函數(shù)可以從上面的代碼看出患久,我們需要對(duì)這個(gè)函數(shù)使用@Provides
注解,然后浑槽,我們這里需要傳入兩個(gè)參數(shù)蒋失,一個(gè)MainActivity引用,一個(gè)User對(duì)象桐玻。那么篙挽,這兩個(gè)參數(shù)從何而來呢?
細(xì)心的同學(xué)可能會(huì)發(fā)現(xiàn),我上面的代碼中還定義了兩個(gè)函數(shù)镊靴,分別為providesUser
和providesActivity
嫉髓,沒錯(cuò)观腊,這里providesMainPresenter
的兩個(gè)參數(shù)就是通過這兩個(gè)函數(shù)來獲取的。如果沒有聲明這兩個(gè)函數(shù)的話算行,編譯期間會(huì)報(bào)錯(cuò)梧油。
attention:
類必須用@Module標(biāo)注
用@Provides注解的函數(shù)需要以provides開頭,然后后面接什么內(nèi)容都可以州邢,看自己喜歡儡陨,事實(shí)上,經(jīng)過我的測(cè)試量淌,我把providesActivity()改成providesA()同樣是可以注入成功的骗村。
因?yàn)椋@里是根據(jù) 返回值類型 來標(biāo)識(shí)的呀枢,方法名并不重要胚股,只需要保證以provides開頭即可。
前面說裙秋,@Inject 做的是將依賴對(duì)象注入到目標(biāo)中琅拌,@Module 提供依賴對(duì)象。它們兩個(gè)之間的聯(lián)系誰來搭建呢? Component就出現(xiàn)了摘刑。
-
編寫Component进宝,搭建@Inject和@Module的橋梁 (第三步)
@Component(modules = MainModule.class) public interface MainComponent { void inject(MainActivity activity);//參數(shù)要寫成對(duì)應(yīng)的activity,不能錯(cuò) }
說明:
· Component要用@Component注解來標(biāo)識(shí)枷恕,并通過(modules = xxx.class)綁定對(duì)應(yīng)module
· 聲明一個(gè)inject方法党晋,之后在MainActivity會(huì)用到。(因?yàn)镃omponent還需要建立與@Inject的聯(lián)系)
· Component的作用就是搭建@Inject和@Module的橋梁徐块,從@Module中獲取依賴并將依賴注入給@Inject未玻。
所以,
mdules= xxx.class的xxx
和inject方法的參數(shù)
是我們每次對(duì)不同的activity建立不同的component要更改的代碼。
- 接下來胡控,需要編譯扳剿。AndroidStudio -> Build -> Make Project (第四步)
編譯后,MainComponent生成一個(gè)DaggerMainComponent類铜犬,這個(gè)類就是我們最后一步在MainActivity里要畫上句點(diǎn) 用到的。
-
在對(duì)應(yīng)Activity的onCreate方法里編寫build代碼轻庆,完成注入癣猾。(最后)
public class MainActivity extends AppCompatActivity { @Inject MainPresenter mainPresenter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... //build代碼開始 DaggerMainComponent.builder() .mainModule(new MainModule(this))//DaggerMainComponent與MainActivityModule的實(shí)例綁定 //mainModule該方法名和MainModule是有關(guān)的,編譯時(shí)生成 .build() .inject(this);//該方法就是MainComponent接口的inject(),傳入當(dāng)前MainActivity的引用 //build代碼結(jié)束 ... mainPresenter.showUserName(); }
}
MainComponent指定的module是MainModule余爆,DaggerMainComponent就會(huì)有一個(gè)名為mainModule的方法纷宇,我們需要調(diào)用它,并傳入?yún)?shù)蛾方,這里我們直接new了一個(gè)MainModule進(jìn)去像捶。
到這里代碼就全部結(jié)束了上陕。上面的代碼運(yùn)行起來的結(jié)果就是在MainActivity的TextView中顯示了一串字符串"user form MainModule",雖然例子簡(jiǎn)單,但是基本上實(shí)現(xiàn)了簡(jiǎn)單依賴注入拓春,希望對(duì)于Dagger2的入門有點(diǎn)啟發(fā)释簿。
梳理思路,概括性講述注入流程
上面是按照編程的順序書寫的硼莽,最后我們按依賴注入的流程梳理下思路庶溶。
-
創(chuàng)建Component(橋梁),并調(diào)用注入方法懂鸵。
// 構(gòu)造橋梁對(duì)象 MainComponent component = DaggerMainComponent.builder().mainModule(new MainModule()).build(); //注入 component.inject(this);
-
Dagger框架查找當(dāng)前類中帶有@Inject的成員變量偏螺。
@Inject //標(biāo)明需要注入的對(duì)象 MainPresenter MainPresenter;
-
根據(jù)成員變量的類型從Module中查找哪個(gè)有@Provides注解的方法返回值為當(dāng)前類型。
@Provides // 關(guān)鍵字匆光,標(biāo)明該方法提供依賴對(duì)象 MainPresenter providesMainPresenter(){ //提供MainPresenter對(duì)象 return new MainPresenter(); }
最后的最后套像,回答個(gè)很多網(wǎng)友的疑問:
Q: 如果被依賴的類構(gòu)造函數(shù)需要多傳一個(gè)參數(shù),那每個(gè)注入的類中终息,不都得改變嗎?
A: Dagger會(huì)自己找到需要的新的依賴夺巩,Module 在創(chuàng)建的時(shí)候應(yīng)該要求最低限度的參數(shù),比如當(dāng)前Context采幌,而不是傳入所有需要的參數(shù)劲够,不然的話 Dagger系統(tǒng)就沒有意義了,我們還是手動(dòng)維護(hù)依賴休傍。比如現(xiàn)在我們?cè)贛ainPresenter增加一個(gè)構(gòu)造方法多傳一個(gè)參數(shù)(C c)征绎。 你只需要修改MainModule,首先創(chuàng)建個(gè)providesC()指明如何創(chuàng)建C實(shí)例磨取,return c;再創(chuàng)建個(gè)providesPresenter2(...參數(shù)省略) return MainPresenter(activity,user,c)即可人柿。MainActivity 是不需要做任何改變的。
demo源碼
只提供了基本原型忙厌。杜絕花哨凫岖,沒有封裝。讓想要快速了解答案的讀者少走彎路逢净。
只有親手做的封裝才是自己的哥放。
感謝
Dagger2從入門到放棄再到恍然大悟
Android:dagger2讓你愛不釋手-終結(jié)篇
Dagger2 這次入門就不用放棄了