【Android】Dagger2从入门到再入门

一.认识Dagger2

Dagger2 是一个Android依赖注入框架,由谷歌开发,最早的版本Dagger1 由Square公司开发。依赖注入框架主要用于模块间解耦,提高代码的健壮性和可维护性。年初的时候就已经接触到dagger2,当时只是看了几篇博文,简单的了解了下,记得当初的感觉也是云里雾里,并未真正的理解dagger,时隔几个月,再次学习它,对dagger有了新的认识,在此作下记录,以便以后查阅,也希望给正在看本文的你有些许帮助;

Dagger2 Github官网网址:https://github.com/google/dagger

Dagger2的主要工作流程分为以下几步:

  • 将依赖需求方实例传入给Component实现类;

  • Component实现类根据依赖需求方实例中依赖声明,来确定该实例需要依赖哪些对象;

  • 确定依赖对象后,Component会在与自己关联的Module类中查找有没有提供这些依赖对象的方法,有的话就将Module类中提供的对象设置到依赖需求方实例中;

这里写图片描述

二.配置build.gradle

咱们废话少说,下面介绍一下如何使用dagger进行依赖注入;

由于 Dagger 使用 apt 生成代码,给project的build.gradle添加如下配置:

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.2.2'
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

moudle的build.gradle引入需要的库(这里只贴出关键代码):

apply plugin: 'com.android.application'
apply plugin: 'com.neenbedankt.android-apt' // 注释处理

······

dependencies {
    ······
    compile 'com.google.dagger:dagger:2.0.2'
    compile 'com.google.dagger:dagger-compiler:2.0.2'
    provided 'org.glassfish:javax.annotation:10.0-b28'
}

三.创建Module

现在的需求是页面上有个按钮,点击按钮后获取student要说的话,Toast显示出来;student的实例的创建咱们就使用dagger的方式来进行注入,页面效果如下:

这里写图片描述

1.首先创建一个Student学生类

public class Student {

    private String name;

    private String sayStr;

    public Student() {
    }

    public Student(String name, String sayStr) {
        this.name = name;
        this.sayStr = sayStr;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSayStr() {
        return sayStr;
    }

    public void setSayStr(String sayStr) {
        this.sayStr = sayStr;
    }
}

2.创建StudentMoudle类,用于提供student对象,module类需要在类上方添加@Module注解,@Provides作用是声明Module类中哪些方法是用来提供依赖对象的,当Component类需要依赖对象时,他就会根据返回值的类型来在有@Provides注解的方法中选择调用哪个方法;

@Module
public class StudentMoudle {

    @Provides
    public Student provideIStudent()
    {
        Student student = new Student();
        student.setName("张三");
        student.setSayStr("一天不装逼,浑身难受");
        return student;
    }
}

四.创建Component

@Component注解有modules和dependencies两个属性,这两个属性的类型都是Class数组,modules的作用就是声明该Component含有哪几个Module,当Component需要某个依赖对象时,就会通过这些Module类中对应的方法获取依赖对象,dependencies属性用来标识继承关系的,通过指定dependencies属性,可以继承其他Component;现在我们来创建StudentComponent:

@Component(modules = StudentMoudle.class)
public interface StudentComponent {
    //此处的MainActivity参数是指需要注入到哪个类
    void inject(MainActivity activity);
}

注:写好module和component类后,Dagger2并不会自动创建对应的类,需要我们点击make poject选项或者make module;编译完成后就会生成DaggerStudentComponent类,命名规则是默认的,Dagger+“你的Component的名字”,然后我们就可以使用如下代码进行注入操作:

DaggerStudentComponent.builder().studentMoudle(new StudentMoudle()).build().inject(this);

五.注入对象,查看结果

在MainActivity中声明Student依赖:

public class MainActivity extends AppCompatActivity {

    private Button btnShow;

    @Inject
    Student student;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initInject();
        initView();
    }

    private void initInject() {
        DaggerStudentComponent.builder().studentMoudle(new StudentMoudle()).build().inject(this);
    }

    private void initView() {
        btnShow = (Button) findViewById(R.id.btn_show);
        btnShow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(MainActivity.this, student.getName()+"说:"+student.getSayStr(), Toast.LENGTH_SHORT).show();
            }
        });
    }
}

效果图:上面呢,上面呢,上面呢!!

这里写图片描述

六.构造函数,直接注入

1.我们新建Teacher类,在构造函数上添加@Inject注解

public class Teacher {

    private String name;

    @Inject
    public Teacher() {
    }

    public Teacher(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

2.注入对象,编译后运行

public class MainActivity extends AppCompatActivity {

    private Button btnTeacher;

    @Inject
    Teacher teacher;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }
    private void initView() {
        btnTeacher = (Button) findViewById(R.id.btn_teacher);

        btnTeacher.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(MainActivity.this, "teacher = "+teacher, Toast.LENGTH_SHORT).show();
            }
        });
    }

3.结果,对象创建成功

这里写图片描述

如果我们把@Inject注解放在有参数的构造函数上,如何使用呢?

4.我们来修改下Teacher类,把注解@Inject放在有参数的构造上,此处的参数我们给了个student;

public class Teacher {

    private Student student;

    public Teacher() {
    }

    @Inject
    public Teacher(Student student) {
        this.student = student;
    }

    public Student getStudent() {
        return student;
    }

    public void setStudent(Student student) {
        this.student = student;
    }
}

5.编译,运行,打印Teacher类中的student的name

btnTeacher.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(MainActivity.this, "teacher student = "+teacher.getStudent().getName(), Toast.LENGTH_SHORT).show();
            }
        });

效果如下,同样可以拿到实例,当有参数的时候,dagger会从已有的依赖中注入需要的参数,其实获取student的流程就和上面注入student的例子是一样的;

这里写图片描述



这一篇先介绍这么多,下一篇将介绍@Singleton,@Scope等其他注解的使用;

参考链接:

1.Dagger2 入门,以初学者角度
2.Dagger2使用初步

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值