Dagger2 的簡單使用

Dagger2是一個Java和Android的依賴注入框架.
本文介紹Android中dagger2的基本使用.
其中包括@Inject, @Component, @Module和@Provides註解的使用.

使用依賴注入的好處
1.使用類和被依賴的對象構造分開,這樣如果我們需要改變被依賴類的構造方法,不必改動每一個使用類.
2.對各種被依賴類的實例,可以只構造一次.
3.當我們需要更換一種實現時,只需要保證接口一致.
4.利於單元測試,我們可以方便地mock依賴類的對象.
優點總結: 創建對象和使用對象分離, 模塊化增強.

註解說明:
@Inject: 通常在需要依賴的地方使用這個註解。換句話說,你用它告訴Dagger這個類或者字段需要依賴注入。這樣,Dagger就會構造一個這個類的實例並滿足他們的依賴。

@Module: Modules類裏面的方法專門提供依賴,所以我們定義一個類,用@Module註解,這樣Dagger在構造類的實例的時候,就知道從哪裏去找到需要的 依賴。modules的一個重要特徵是它們設計爲分區並組合在一起(比如說,在我們的app中可以有多個組成在一起的modules)。

@Provide: 在modules中,我們定義的方法是用這個註解,以此來告訴Dagger我們想要構造對象並提供這些依賴。

@Component: Components從根本上來說就是一個注入器,也可以說是@Inject和@Module的橋樑,它的主要作用就是連接這兩個部分。 Components可以提供所有定義了的類型的實例,比如:我們必須用@Component註解一個接口然後列出所有的@Modules組成該組件,如 果缺失了任何一塊都會在編譯的時候報錯。所有的組件都可以通過它的modules知道依賴的範圍。

@Scope: Scopes可是非常的有用,Dagger2可以通過自定義註解限定註解作用域。後面會演示一個例子,這是一個非常強大的特點,因爲就如前面說的一樣,沒 必要讓每個對象都去了解如何管理他們的實例。在scope的例子中,我們用自定義的@PerActivity註解一個類,所以這個對象存活時間就和 activity的一樣。簡單來說就是我們可以定義所有範圍的粒度(@PerFragment, @PerUser, 等等)。

Qualifier: 當類的類型不足以鑑別一個依賴的時候,我們就可以使用這個註解標示。例如:在Android中,我們會需要不同類型的context,所以我們就可以定義 qualifier註解“@ForApplication”和“@ForActivity”,這樣當注入一個context的時候,我們就可以告訴 Dagger我們想要哪種類型的context。

Dagger2 具體使用案例:
1.配置
在AppMode 下的build.gradle進行配置,然後同步就可以導入相關dagger2的包:

/***************************************使用dagger2需要的配置Start*****************************************/
apply plugin: 'com.neenbedankt.android-apt'
buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

/************使用dagger2需要的配置End************************/

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:26.0.0-alpha1'

 /************dagger2使用需要的庫start***********************/

    compile "com.google.dagger:dagger:2.9"
    apt 'com.google.dagger:dagger-compiler:2.9'
//Dagger2中會用到@Generated註解,而AndroidSDK中沒有javax.anotation.Generated.class,所以在 Android 項目要添加此句
    provided 'org.glassfish:javax.annotation:10.0-b28'

 /***********dagger2使用需要的庫end*************************/

}

2.創建一個類Student用於測試Mode

/**
 * Created by lixby on 2017/8/10.
 */
public class Student {

    private String sName;

    private String sSex;

    private String sAge;

    public Student(String sName, String sSex, String sAge) {
        this.sName = sName;
        this.sSex = sSex;
        this.sAge = sAge;
    }

    public String getsAge() {
        return sAge;
    }

    public void setsAge(String sAge) {
        this.sAge = sAge;
    }

    public String getsName() {
        return sName;
    }

    public void setsName(String sName) {
        this.sName = sName;
    }

    public String getsSex() {
        return sSex;
    }

    public void setsSex(String sSex) {
        this.sSex = sSex;
    }

    public void showStudentInfo(){
        Log.i("lixby","student Name:"+sName);
        Log.i("lixby","student sSex:"+sSex);
        Log.i("lixby","student sAge:"+sAge);

    }
}

3.創建StudentModule,用於體提供Student實例給其他地方使用,代碼很簡單,一定要注意提供@Module 和@Provides 註解,要不無法沒被Dagger2識別:

/**
 * Created by lixby on 2017/8/10.
 */
@Module
public class StudentModule {


    @Provides
    public Student provideStudent(){
        return new Student("小明","男","18");
    }


}

4.創建AppComPonent

/**
 * Created by lixby on 2017/8/10.
 */

@Singleton
@Component(modules = {ApplicationModule.class,StudentModule.class})
public interface AppComPonent {
    //MainActivity 目標類
    void inject(MainActivity mainActivity);

}

Component是注入器,它一端連接目標類,另一端連接目標類依賴實例,它把目標類依賴實例注入到目標類中。上面的Module是一個提供類實例的類,所以Module應該是屬於Component的實例端的(連接各種目標類依賴實例的端),Component的新職責就是管理好Module,Component中的modules屬性可以把Module加入Component,modules可以加入多個Module。

第三和第四中,Module中的創建類實例方法用Provides進行標註,Component在搜索到目標類中用Inject註解標註的屬性後,Component就會去Module中去查找用Provides標註的對應的創建類實例方法。

5.按照上面步驟完成Module和Component的創建,然後執行Rebuild Project就會自動生成對應的關聯文件。
這裏寫圖片描述
6.初始化AppComPonent

/**
 * Created by lixby on 2017/8/10.
 */
public class MyApplication extends Application{

    static AppComPonent mAppComPonent;

    @Override
    public void onCreate() {
        super.onCreate();
        inItDaggerModule();
    }


    private void inItDaggerModule(){
        mAppComPonent= DaggerAppComPonent.builder()
                .applicationModule(new ApplicationModule(this))
                .studentModule(new StudentModule())
                .build();

    }


    public static AppComPonent getComponent() {
        return mAppComPonent;
    }


}

7.在MainActivity中通過@Inject 將Student注入,就可以使用Student 實例了:

public class MainActivity extends AppCompatActivity {

    @Inject
    Student mStudent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        MyApplication.getComponent().inject(this);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mStudent.showStudentInfo();

    }
}

總結:
Inject,Component,Module,Provides是dagger2中的最基礎最核心的知識點。奠定了dagger2的整個依賴注入框架。

Inject主要是用來標註目標類的依賴和依賴的構造函數
Component它是一個橋樑,一端是目標類,另一端是目標類所依賴類的實例,它也是注入器(Injector)負責把目標類所依賴類的實例注入到目標類中,同時它也管理Module。
Module和Provides是爲解決第三方類庫而生的,Module是一個簡單工廠模式,Module可以包含創建類實例的方法,這些方法用Provides來標註

這裏寫圖片描述

這個Demo很簡單,只是初識,還需要進一步在實踐中去使用和總結。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章