初學(xué)者dagger2簡(jiǎn)明教程

本文更新于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ù)镊靴,分別為providesUserprovidesActivity嫉髓,沒錯(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的xxxinject方法的參數(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 這次入門就不用放棄了

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市爹土,隨后出現(xiàn)的幾起案子甥雕,更是在濱河造成了極大的恐慌,老刑警劉巖胀茵,帶你破解...
    沈念sama閱讀 216,324評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件砂客,死亡現(xiàn)場(chǎng)離奇詭異正罢,居然都是意外死亡纫普,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門附鸽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人瞒瘸,你說我怎么就攤上這事坷备。” “怎么了挨务?”我有些...
    開封第一講書人閱讀 162,328評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵击你,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我谎柄,道長(zhǎng)丁侄,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,147評(píng)論 1 292
  • 正文 為了忘掉前任朝巫,我火速辦了婚禮鸿摇,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘劈猿。我一直安慰自己拙吉,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,160評(píng)論 6 388
  • 文/花漫 我一把揭開白布揪荣。 她就那樣靜靜地躺著筷黔,像睡著了一般。 火紅的嫁衣襯著肌膚如雪仗颈。 梳的紋絲不亂的頭發(fā)上佛舱,一...
    開封第一講書人閱讀 51,115評(píng)論 1 296
  • 那天,我揣著相機(jī)與錄音挨决,去河邊找鬼请祖。 笑死,一個(gè)胖子當(dāng)著我的面吹牛脖祈,可吹牛的內(nèi)容都是我干的肆捕。 我是一名探鬼主播,決...
    沈念sama閱讀 40,025評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼盖高,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼慎陵!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起喻奥,我...
    開封第一講書人閱讀 38,867評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤席纽,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后映凳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體胆筒,經(jīng)...
    沈念sama閱讀 45,307評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡邮破,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,528評(píng)論 2 332
  • 正文 我和宋清朗相戀三年诈豌,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了仆救。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,688評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡矫渔,死狀恐怖彤蔽,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情庙洼,我是刑警寧澤顿痪,帶...
    沈念sama閱讀 35,409評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站油够,受9級(jí)特大地震影響蚁袭,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜石咬,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,001評(píng)論 3 325
  • 文/蒙蒙 一揩悄、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧鬼悠,春花似錦删性、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至它掂,卻和暖如春巴帮,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背群发。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評(píng)論 1 268
  • 我被黑心中介騙來泰國(guó)打工晰韵, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人熟妓。 一個(gè)月前我還...
    沈念sama閱讀 47,685評(píng)論 2 368
  • 正文 我出身青樓雪猪,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親起愈。 傳聞我的和親對(duì)象是個(gè)殘疾皇子只恨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,573評(píng)論 2 353

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