你所看到較輕松的Dagger2(使用方式)

上篇簡單介紹了一下依賴注入以及為什么我們要用依賴注入.

這篇主要介紹一下Dagger2的使用方法 并分析一下Dagger2的源碼看看它是怎么實現的。

Dagger2用法還是蠻簡單的,首先我們在Project根目錄的gradle中添加apt依賴

//添加apt依賴


classpath'com.neenbedankt.gradle.plugins:android-apt:1.8'

在我們的Module app gradle里添加apt插件

//添加如下代碼,應用apt插件


applyplugin:'com.neenbedankt.android-apt'

然后添加dagger2依賴以及注解依賴


compile'com.google.dagger:dagger:2.4'

apt'com.google.dagger:dagger-compiler:2.4'

//java注解

compile'org.glassfish:javax.annotation:10.0-b28'

好了喝杯咖啡等待我們gradle構建完畢吧. 所有依賴添加完后我們就可以使用了.

這里我們以一個MVP小例子舉例,先介紹Dagger2的第一種用法
我們傳統的MVP寫法基本似這樣子滴
這是我們創建的Activity v層:


public class MainActivity extends AppCompatActivity implements BaseView{

    DemoPresenter mDemoPresenter;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

         super.onCreate(savedInstanceState);

         setContentView(R.layout.activity_main);

         @Override

         public voidsetXxx() {

         }

}

我們創建一個Presenter:

public class DemoPresenter {

         private BaseView mBaseView;

         private DemoModule mDemoModule;

         public DemoPresenter(BaseView baseView) {

         mBaseView= baseView;

         mDemoModule=newDemoModule();

 }

          public void   getPerson() {

          Person person =mDemoModule.getPerson();

          if(person.mMsg.equals("1")) {

                mBaseView.setXxx();

             }

       }

}

然后創建一個Module :

public class DemoModule {

        publicPersongetPerson(){

            Person p=null;

           try{

               Thread.sleep(1000);

               p=newPerson("wubo","11");

             }catch(InterruptedException e) {

                e.printStackTrace();

             }

           return  p;

        }

}

好了這里我們Module 用Thread睡以下假裝請求接口數據,好傳統我們做法是在Activity的onCreate()中

DemoPresenter demoPresenter =new DemoPresenter(this);

然后在合適的地方調用

demoPresenter.getPerson(); 

現在有了Dagger2我們就不需要這樣寫了 我們可以在MainActivity presenter成員變量上加上@Inject注解

@Inject
DemoPresenter  mDemoPresenter;  

然后在presenter的構造上同樣加上@Inject注解

public class DemoPresenter {
       
         private BaseView mBaseView;

         private DemoModule mDemoModule;

         @Inject
         public DemoPresenter(BaseView baseView) {
          mDemoModule=newDemoModule();
         }
          public void   getPerson() {

          Person person =mDemoModule.getPerson();

          if(person.mMsg.equals("1")) {

                mBaseView.setXxx();
             }
          }
     }

當我們在MainActivity用@Inject標注后Dagger會去標注的這個類的構造上尋找是否同樣有@Inject標注如果有的話生成這個對象,當然如果構造上面你沒有加@Inject那么是不會生成對象的請看官網文檔說明

If your class has @Inject-annotated fields but no @Inject-annotated constructor, Dagger will inject those fields if requested, but will not create new instances. Add a no-argument constructor with the @Inject annotation to indicate that Dagger may create instances as well.

好了現在注解加了對象也生成了,可是怎么把生成對象添加到我們依賴的MainActivity中呢?這就要用到Component,Component是一個橋梁它連接我們的宿主和依賴
我們新創建一個Compnoent接口,注意Component是不需要我們自己去實現的我們只需要去定義接口和實現方法,具體實現細節Dagger會自動幫我們生成是不是灰常貼心。

@Component (modules = {Module.class})
public interface Compnoent {
    void inject(MainActivity mainActivity);
}
(modules = {Module.class})

這里面我們要說明一下這個Component需要依賴哪些Module我們可以指定多個這里我們指定Module
貼上Module代碼

@dagger.Module
public class Module {

    private BaseView mBaseView;

    public Module(BaseView baseView){

        mBaseView = baseView;
    }

    @Provides
    public BaseView getBaseView(){
        return mBaseView;
    }
}

這里我創建了一個Module構造里面參數傳遞宿主類也就是我們的MainActivity至于為什么這么繼續看,下面定義了一個方法使用了
@Provides 咦這是什么東東,這個就是我們提供依賴對象的,比如
說我們可以new出來的對象可以用@Inject去注解構造,那么無法new
出來的對象怎么使用@Inject呢,比如

Interfaces can’t be constructed.
Third-party classes can’t be annotated.
Configurable objects must be configured!

所以Dagger給我們提供了Provides , Provides 是這樣的在Dagger幫我們去創建依賴對象時,依賴對象中存在依賴對象或者構造中存在參數的時候,Dagger是沒有這么智能也幫我們自動去生成的,這個時候Dagger會去@Module 類中 @Provides 依賴的方法找 哪個方法返回值復核依賴那么就賦值給這個依賴。

好了所以需要添加的代碼我們添加完畢,現在我們在需要依賴的地方(比如MainActivity中的onCreate()中)調用

//方法一
DaggerCompnoent.builder().module(new Module(this)).build().inject(this);

就可以使用mDemoPresenter了

接下來我們介紹第二種依賴方式:
第二種方法我們不需要去使用@Inject注解了,其實我個人認為第二種方法不是依賴注入了因為這種方式生成的對象并不是Dagger注入進去的而是我們自己生成的只不過不是在宿主中生成了,可能有點繞我們繼續看下去就會清除了。
第二種方式我們把所有使用@Inject全部去掉, 同樣的還需要創建Module和Compnoent,Module創建的代碼跟方式跟上面的一模一樣,Compnoent 需要我們改一改

//之前我們是這樣創建的
@Component (modules = {Module.class})
public interface Compnoent {
    void inject(MainActivity mainActivity);
}

//現在我們改成這樣不需要傳遞宿主類了
@Component (modules = {Module.class})
public interface Compnoent {
    DemoPresenter getPresenter();
}

我們看到上面我們把代碼改成了返回一個DemoPresenter 的方法,為什么要這么做呢,因為Dagger會幫我們去實現Component 注解的所有方法,當Dagger實現getPresenter()方法需要返回一個DemoPresenter 時候它怎么辦呢?我們前面說了所有依賴中需要的依賴Dagger都會去Module中的Provide去找,所以我們前面的Module中同樣需要改動的,我們添加一個
拿到DemoPresenter 的方法,你不添加Dagger怎么找的到呢,

@dagger.Module
public class Module {

    private BaseView mBaseView;

    public Module(BaseView baseView){

        mBaseView = baseView;
    }
    @Provide
    public DemoPresenter getPresenter(){
        return new DemoPresenter (mBaseView );
    }
}

現在我們可以在MainActivity中這么調

 //方法二
DemoPresenter mDemoPresenter =DaggerCompnoent.builder().module(new Module(this)).build().getPresenter();

這樣我們就直接生成了一個DemoPresenter 對象
我們總結一下二種方式的區別
方法一: 通過在宿主類(MainActivity)中的依賴上添加@Inject,然后在依賴類的構造上@Inject ,Dagger自動生成依賴類的對象,然后創建一個@Module依賴的Module類,通過Module的構造方法傳入宿主類,聲明成員變量,然后添加一個@Provide依賴的方法,方法返回宿主對象也就是我們聲明的成員變量.最后我們創建一個@Component依賴的Component接口Component 要申明我們要依賴的Module (modules = {Module.class}) Component接口中申明一個方法,方法中參數傳遞我們的宿主對象, void inject(MainActivity mainActivity);
然后在宿主類中調用
DaggerCompnoent.builder().module(new Module(this)).build().inject(this);

方法二:
創建一個@Module依賴的Module類,通過Module的構造方法傳入宿主類,聲明成員變量,然后添加一個@Provide依賴的方法,方法返回宿主對象也就是我們聲明的成員變量,再多添加一個@Provide


Dagger還提供了@Signal

 @Provide
    public DemoPresenter getPresenter(){
        return new DemoPresenter (mBaseView );
    }

然后Component接口改成這樣

@Component (modules = {Module.class})
public interface Compnoent {
    DemoPresenter getPresenter();
}

宿主類中我們這樣直接生成依賴對象

 //方法二
DemoPresenter mDemoPresenter =DaggerCompnoent.builder().module(new Module(this)).build().getPresenter();

二種方式已經介紹完畢,艾瑪,寫的累死寶寶了,好了,使用方法介紹完畢,現在我們解開Dagger神秘的面紗看看Dagger是怎么自動生成代碼的是怎么把依賴注入到宿主類中的,敬請期待你所看到最輕松的Dagger2講解(源碼分析)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,563評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,694評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,672評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,965評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,690評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,019評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,013評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,188評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,718評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,438評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,667評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,149評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,845評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,252評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,590評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,384評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,635評論 2 380

推薦閱讀更多精彩內容