Dagger2 小記

0x00 開始

以最無趣的 “Hello World” 開始吧。

public class Hello {
    
    public String greeting(){
        return "Hello World.";
    }
    
}

然后在 TextView 中顯示,常規(guī)的方法是:

Hello hello = new Hello();
textViewHello.setText(hello.greeting());

那么,如果使用 Dagger2 進(jìn)行依賴注入,我們使用 @Inject 將 Hello 實例注入:

@Inject Hello hello;

...

textViewHello.setText(hello.greeting());

這里存在一個問題:要怎么實例化 Hello 呢? Dagger2 提供 @Inject 標(biāo)注,在構(gòu)造函數(shù)中標(biāo)注后,當(dāng)需要實例化時,Dagger2 就會調(diào)用這個構(gòu)造函數(shù):

@Singleton
public class Hello {

    @Inject public Hello() {}
    
    public String greeting(){
        return "Hello World.";
    }
    
}

PS: 加入 Hello 也需要注入其他類呢? @Inject 同樣輕松搞定,構(gòu)造函數(shù)參數(shù)以及類成員屬性均可輕松注入。

這時依然無法工作,如果你運行程序,會產(chǎn)生悲傷的 NullPointerException,那么還差什么呢?

我們需要創(chuàng)建一個Component,Component是Provider和Injector之間的橋梁。

@Singleton
@Component
public interface DemoComponent {

    void inject(MainActivity activity);

}

Dagger2 會自動生成一個 DaggerDemoComponent,在 Activity 中調(diào)用注入:

DaggerDemoComponent.create().inject(this);

打完收工!

當(dāng)然,你還需要通過 gradle 引入 Dagger2:

...
apply plugin: 'com.neenbedankt.android-apt'

buildscript {
    repositories {
        jcenter()
    }

    dependencies {
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'
    }
}

...

dependencies {
    ...
    provided 'javax.annotation:javax.annotation-api:1.2'
    apt 'com.google.dagger:dagger-compiler:2.0.2'
    compile 'com.google.dagger:dagger:2.0.2'
}

0x01 進(jìn)階

如上所述,我們自己寫的代碼可以通過 @Inject 實例化并注入,但若是第三方庫提供的類呢?

這時需要用到 @Module, @Provide:

@Module

Module 是擁有可以提供依賴的函數(shù)的類,我們定義一個類,標(biāo)注為 @Module,然后 Dagger2 就知道哪里可以找到構(gòu)建一個對象所需要的依賴?yán)病6?Module 被設(shè)計為可以被分割和組合的模式,有益于模塊的劃分。

@Provide

在標(biāo)注為 @Module 的類中的函數(shù)可以標(biāo)注為 @Provide, 標(biāo)示可以提供相應(yīng)的依賴,函數(shù)的前綴必須為 provides.

@Module
public class DemoModule {

    @Provides @Singleton
    public GithubService provideGithubService() {
        return new GithubService();
    }

}

然后我們要告知 Component 使用這個 Module:

@Singleton
@Component(modules = {DemoModule.class})
public interface DemoComponent {

    void inject(MainActivity activity);

}

@Component 可以通過 dependencies 申明依賴依他的 @Component。

@Singleton

這是標(biāo)示一個單例的注釋,可以和 @Provide 共同標(biāo)注一個函數(shù),標(biāo)示這個函數(shù)返回的對象都是單例的,也可以和 @Component 一起標(biāo)注一個Component,標(biāo)示這個 Component 的 Scope 是全局的。

@Scope

Scopes 非常的有用,Dagger2 可以通過自定義注解限定注解作用域。

@Qualifier

當(dāng)類的類型不足以鑒別一個依賴的時候,我們就可以使用這個注解標(biāo)示。

例如:在Android中,我們會需要不同類型的 Context,所以我們就可以定義 Qualifier 注解 @ForApplication 和 @ForActivity,這樣當(dāng)注入一個 Context 的時候,我們就可以告訴 Dagger 我們想要哪種類型的 Context。

0x02 參考

Dagger 2

Tasting Dagger 2 on Android

Dependency injection with Dagger 2 - the API

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

  • 本文的分析基于dagger2的2.7版本。 谷歌開發(fā)維護(hù)的Dagger2出來有很長時間了,目前在很多開源項目上也能...
    sososeen09閱讀 13,655評論 31 108
  • 部分內(nèi)容參考自:[Android]使用Dagger 2依賴注入 - DI介紹(翻譯)[Android]使用Dagg...
    AItsuki閱讀 47,749評論 66 356
  • 昨晚一宿沒有怎么睡好,本來忙完再加上玩了一天很累,但凌晨兩點突然危機(jī)意識就開始爆棚。我覺得一個老大,或許在除...
    熙熙Breathe閱讀 265評論 0 2
  • 2017.7.15學(xué)習(xí)打卡: 1.聽李杲老師腦場講座的視頻,受益匪淺。能真切的感受到來自身邊環(huán)境、他人和自己的正負(fù)...
    斯寒閱讀 236評論 0 2
  • 須知 background-size 屬性規(guī)定背景圖片的尺寸。在 CSS3 之前,背景圖片的尺寸是由圖片的實際尺寸...
    c59ffede9db6閱讀 175評論 0 0