Dagger2 初体验

来源:互联网 发布:什么牌的网络机顶盒好 编辑:程序博客网 时间:2024/06/02 05:43

上一篇了解了Dagger是什么东西,以及使用它的优点。 接下来就来写个最简单的demo试试水。

先来看下在不使用Dagger的情况下, 在一个Activity中使用User bean类的方式,很简单如下所示:

User.java

/** * Created by Danny on 17/8/30. */public class User {    private String name;    private int age;    public User(String name) {        this.name = name;    }    public User(int age) {        this.age = age;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getAge() {        return age;    }}

MainActivity.java

User user;public void initData() {        textView = ((TextView) findViewById(R.id.tv1));        user = new User();        user.setName("Danny");        textView.setText("user is " + user.getName());}

很简单,只要在MainActivity中声明一个全局变量User, 然后在initData方法中初始化User并设置name属性,然后将其设置到TextView控件上


接下来看一下如何使用Dagger将User进行依赖注入,并显示到TextView上

首先在Project的build.gradle中添加如下依赖

buildscript {    repositories {        jcenter()    }    dependencies {        classpath 'com.android.tools.build:gradle:2.3.0'        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    }}ext {    daggerVersion = '2.11'}

之后在app的build.gradle中添加如下依赖

// dagger support    apt "com.google.dagger:dagger-compiler:$rootProject.daggerVersion"    provided 'org.glassfish:javax.annotation:10.0-b28'    compile "com.google.dagger:dagger:$rootProject.daggerVersion"

代码中首先将MainActivity中的user变量,添加@Inject注解,如下所示

@InjectUser user;public void initData() {        textView = ((TextView) findViewById(R.id.tv1));        //使用Dagger,不再需要初始化User对象        //user = new User();        user.setName("Danny");        textView.setText("user is " + user.getName());}

然后在User.java的构造器方法也添加@Inject注解,如下所示:

/** * Created by Danny on 17/8/30. */public class User {    private String name;    private int age;    @Inject    public User() {        Log.e("DANNY", "default construction called");    }    public User(String name) {        this.name = name;    }    public User(int age) {        this.age = age;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getAge() {        return age;    }}

可以看到在User的空参构造器上添加了@Inject的注解。如果这个时候我们就运行程序会发现报空指针 user为null。 也就是说Dagger并没有成功创建对象并注入到MainActivity中。 这是因为我们少了一个最重要的东西 — Component(在Dagger中,一般叫注射器)。
创建如下类,并用@Component注解

@Singletonpublic interface UserComponent {    void bind(MainActivity mainActivity);}

然后在MainActivity的initData方法中添加如下代码:

public void initData() {        textView = ((TextView) findViewById(R.id.tv1));        //告诉MainActivity,其中@Inject注解的属性都由Dagger进行依赖注入        DaggerUserComponent.builder().build().bind(this);        //使用Dagger,不再需要初始化User对象        //user = new User();        user.setName("Danny");        textView.setText("user is " + user.getName());}

这样就可以成功运行并显示User name到TextView上了

解释一下

  • 在UserComponent接口中添加bind(MainActivity)方法,这个方法的作用就是通知MainActivity,如果在MainActivity中有被@Inject注解的变量则会通过UserComponent这个接口去初始化,并注入MainActivity中
  • 而UserComponent初始化变量的规则就是先找到MainActivity中被@Inject注解的变量(比如User),然后到User类中找到被@Inject注解的构造器,进行初始化new的操作

代码运行流程:以上代码是如何工作的呢?

  • 首先定义一个类User 并在其构造函数用@Inject标注,表示告诉Dagger2这是我的构造函数,如果有地方要用到我,就用该构造函数对我实例化;
  • 创建一个@Component标注的注入器接口,并在注入器中使用 void bind(MainActivity MainActivity);来表明哪里要用到注入器;这里表示MainActivity中要用到该注入器
  • 在MainActivity中对需要注入的类 User用@Inject进行标注,表示该类需要被注入,即实例化;
  • 在MainActivity中对注入器进行初始化DaggerActivityComponent.builder().build().inject(this); 初始化后该注入器就可以正常使用了;
原创粉丝点击