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很简单,只是初识,还需要进一步在实践中去使用和总结。

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