Dagger2使用入门

推荐Dagger2 不错的入门系列传送门:http://www.jianshu.com/p/cd2c1c9f68d4
官网说明文档:https://google.github.io/dagger/users-guide.html

  • Dagger 声明依赖
    Dagger可帮你的应用构造类的实例,并满足它们的依赖关系.它使用javax.inject.Inject注释来标识它感兴趣的构造函数和字段属性。
    一个类需Dagger为其创建实例那么需要为这个类的构造函数添加@Inject注解.当Dagger需要为一个类创建实例时,Dagger会去获取构造函数内参数(也有可能是无参构造函数)并调用对应的构造方法,就像下面这样:
class Thermosiphon implements Pump {
  private final Heater heater;

  @Inject
  Thermosiphon(Heater heater) {
    this.heater = heater;
  }

  ...
}

Dagger可以直接使用@Inject注解获取到属性实例,例如下面的例子中通过@Inject属性获取到了heater和pump的实例.

class CoffeeMaker {
  @Inject Heater heater;
  @Inject Pump pump;

  ...
}

Dagger也可以进行方法注入,不过一般构造函数或字段注入通常是首选.

满足依赖

通常情况下,当你需要一个对应类的实例时,Dagger调用该类的构造函数来创建实例,并将该实例赋值给被@Inject注解的属性字段中.然后实际中的开发任务也有@Inject无法触及的内容:

  1. 接口不能被构造
  2. 第三方类不能注释
  3. 可配置的对象

对于这些@Inject够不着的尴尬情况,请使用 @Provides
注释方法来满足依赖关系。 方法的返回类型定义了它满足哪个依赖关系。如下示例,当需要创建Heater 实例时,provideHeater()将被调用

@Provides 
static Heater provideHeater() {
  return new ElectricHeater();
}

@Provides方法有可能拥有自己的依赖关系,以下代码片段中(providePump()方法拥有自己的依赖关系,Thermosiphon 参数),该方法会返回一个这个Thermosiphon实例.

@Provides 
static Pump providePump(Thermosiphon pump) {
  return pump;
}

@Provides配合 @Module方法一起使用,@Provides一般在被@Module注解的类下使用,例如下面的代码片段:

@Module
class DripCoffeeModule {
@Provides 
static Heater provideHeater() {
    return new ElectricHeater();
  }

@Provides 
static Pump providePump(Thermosiphon pump) {
    return pump;
  }
}

按照惯例,被@Provides注解的方法使用provide 前缀,被@Module注解的类使用module作为后缀.

  • 总结:

一、@Inject 注解 可以用来标准构造函数,同时它也可以被用来标注对象的实例

二、被@Inject标注的对象实例与被@Inject标注的构造函数 通过@Component产生联系(这样对象实例就可以找到自己的构造函数进行初始化了)

三、@Module注解是为第三方类库而生的.在第三方类库上使用Dagger2稍微不同的地方是第三方类库的构造函数使用@Provides注解

四、使用@Inject标注的构造函数(自身代码)与使用@Module+@Provides标注的构造函数 都可以创建 对象实例,@Component 会优先使用@Module+@Provides创建的实例(如果存在的话)

五、当出现有多个@Inject标注的构造函数(或者多个@Module+@Provides标注的构造函数),使用@Qualifier 注解来区分所需使用的构造函数(类似于唯一标识符)

2018年6月15日17:58:30 更新:

1.初步使用

试验用实体类
package com.keytop.test.entity;

import javax.inject.Inject;

/**
 * 创建实体
 * Create by fengwenhua at 2018/6/15
 **/
public class User {
    private String name;


    @Inject
    public User(String name){
        this.name = name;
    }

    public String getName() {
        return name;
    }

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

在该实体的构造函数中,我们通过@Inject注解告诉Dagger,如果需要User实例,可以使用该构造函数生成

实例生产者
package com.keytop.test.module;

import com.keytop.test.entity.User;

import dagger.Module;
import dagger.Provides;

/**
 * Module 实例生产者
 * Create by fengwenhua at 2018/6/15
 **/

@Module
public class MainModule {

    @Provides
    public User providerUser(){
        return new User("姬如雪");
    }
}

使用@Module注解该类,使用@Provides注解生产方法,实例的生产者有个约定,以Module结尾,方法以provider开头,当然如果你不遵守也是可以的.

package com.keytop.test.component;

import com.keytop.test.MainActivity;
import com.keytop.test.module.MainModule;

import dagger.Component;

/**
 * 连接纽带
 * Create by fengwenhua at 2018/6/15
 **/
@Component(modules = {MainModule.class})
public interface MainComponent {

    void inject(MainActivity activity);
    
   //在User 中是没有@Inject注解,因此在代理类中,这个方法其实是废方法哦.
    void inject2(User user);
}

inject(MainActivity activity)这个方法其实你可随便命名,真正在编译的时候,Dagger会检测参数中(在这就是MainActivity )使用有@Inject注解.如果有的话,进行参数注入。否则的它做个有趣的操作,生成个虚构的注入方法.

@Override
  public void inject2(User user) {
    MembersInjectors.<User>noOp().injectMembers(user);//代理类中的废方法
  }

使用

package com.keytop.test;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;

import com.keytop.test.component.DaggerMainComponent;
import com.keytop.test.entity.User;
import com.keytop.test.module.MainModule;

import javax.inject.Inject;

public class MainActivity extends AppCompatActivity {
    private static final String TAG = MainActivity.class.getSimpleName();

    @Inject
    protected User user;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        DaggerMainComponent.builder().mainModule(new MainModule()).build().inject(MainActivity.this);
        // 话说以下的使用方式也没问题,因为当你未指定mainModule时,build()会帮你调用一个无参的构造类
        //DaggerMainComponent.builder().build().inject(MainActivity.this);
        Log(user.getName());
    }

    protected void Log(String message){
        Log.i(TAG, message);
    }

}
运行结果

于2018年7月5日20:04:13更新

2. 模拟调用第三方库

当调用第三方库时,一般情况下我们是没办法去修改它们的源码,因此我们也就没办法给实体类添加@Inject注解了.下面我们引入一个Job类来模拟第三方库调用,我们不准备在其上修改任何代码.它就是一个普通的POJO类.

package com.keytop.test.entity;

/**
 * 职业
 * Create by fengwenhua at 2018/7/5
 **/
public class Job {

    /**职业名称*/
    private String jobName;

    public String getJobName() {
        return jobName;
    }

    public void setJobName(String jobName) {
        this.jobName = jobName;
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,133评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,682评论 3 390
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,784评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,508评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,603评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,607评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,604评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,359评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,805评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,121评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,280评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,959评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,588评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,206评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,442评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,193评论 2 367
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,144评论 2 352

推荐阅读更多精彩内容