Dagger2初探

背景

A类持有B类的引用,如果B类的构造函数发生改变,则A类也需要修改;不仅仅是A类,但凡持有B类引用的地方都需要修改。这个就是 Dagger2 解决的问题。

Dagger2

引入

  1. 在 build.gradle (Project) 添加 apt 插件
dependencies {
    classpath 'com.android.tools.build:gradle:2.3.3'
    classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'
    // NOTE: Do not place your application dependencies here; they belong
    // in the individual module build.gradle files
}
  1. 在 build.gradle 中添加依赖
apply plugin: 'com.android.application'
//应用apt插件
apply plugin: 'com.neenbedankt.android-apt'
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    ...
    // 添加如下引用
    provided 'org.glassfish:javax.annotation:10.0-b28'
    compile 'com.google.dagger:dagger:2.5'
    compile 'com.google.dagger:dagger-compiler:2.5'
}

使用

DaggerActivity需要有一个 **DaggerPresenter **的成员

第一步:创建Module

  1. 创建Module——**Module **的作用是用来提供生成依赖对象的,现在需要注入DaggerPresenter 对象,那么Module的作用就是生成一个DaggerPresenter 对象
  • 该类需要用 @Module 注解
  • 既然需要提供一个DaggerPresenter 对象,那么第一步就应该提供生成DaggerPresenter 对象的方法
  • DaggerPresenter 的构造函数需要DaggerActivity 和User对象,所以第二步需要生成DaggerActivity 和User对象
@Module
public class ActivityModule {
    private DaggerActivity activity;

    public ActivityModule(DaggerActivity activity) {
        this.activity = activity;
    }
  
    //第二步
    @Provides
    public DaggerActivity provideActivity() {
        return activity;
    }

    //第二步
    @Provides
    public User provideUser(){
        return new User("user created in ActivityModule");
    }

  //第一步
    @Provides
    public DaggerPresenter providePresenter(DaggerActivity activity, User user) {
        return new DaggerPresenter(activity,user);
    }
}

第二步:创建Component

@Component(modules = ActivityModule.class)
public interface ActivityComponent {
    void inject1(DaggerActivity activity);
}
  1. Component需要用@Component注解来标识
  2. 同时声明 module
  3. 提供了一个inject1方法,方法名随意,参数不能改

第三步:Make Project

完成之后 **apt **会自动生成一个 以 Dagger 开头的 Component,比如,我们上面写的是 **ActivityComponent **,生成了类名就为 DaggerActivityComponent。这个类我们可以直接使用

第四步:注入Activity

在 **Activity **的 **onCreated **函数中编写如下代码

@Inject
MvpPresenter presenter;

DaggerActivityComponent.builder()
    .activityModule(new ActivityModule(this))
    .build()
    .inject1(this);

首先调用这个了类的 builder(),然后调用 module,调用build,调用Component的inject1方法

这里通过 new MainModule(this) 将 view 传递到 MainModule 里,然后 MainModule 里的 provideMainView() 方法返回这个 View,当去实例化 MainPresenter 时,发现构造函数有个参数,此时会在 Module 里查找提供这个依赖的方法,将该 View 传递进去,这样就完成了 presenter 里 View 的注入

解释说明

在MVP模式中,最常见的一种依赖关系,就是 Activity 持有 presenter 的引用,并在 Activity 中实例化这个 presenter,即 Activity 依赖 presenter,presenter 又需要依赖 View 接口,从而更新 UI

使用Dagger2的话代码如上使用Dagger,

先看 Activity,之前是直接声明 MvpPresenter,现在是在声明的基础上加了一个注解@Inject,表明 MainPresenter 是需要注入到 Activity 中的,使用 @Inject 时,不能用 private 修饰符修饰类的成员属性

然后我们在 MainPresenter 的构造函数上同样加了 @Inject 注解。这样 MainActivity 里的 mainPresenter 与他的构造函数建立了某种联系。这种联系我们可以这样理解,当看到某个类被 @Inject 标记时,就会到他的构造方法中,如果这个构造方法也被 @Inject 标记的话,就会自动初始化这个类,从而完成依赖注入。

这种联系不会凭空建立 ,需要一个桥梁就是我们创建的Component,Component 是一个接口或者抽象类,用 @Component 注解标注


  • @Inject 带有此注解的属性或构造方法将参与到依赖注入中,Dagger2 会实例化有此注解的类
  • @Module 带有此注解的类,用来提供依赖,里面定义一些用 @Provides 注解的以 provide 开头的方法,这些方法就是所提供的依赖,Dagger2 会在该类中寻找实例化某个类所需要的依赖。
  • @Component 用来将 @Inject@Module 联系起来的桥梁,从 @Module 中获取依赖并将依赖注入给 @Inject

注意

  1. Component可以依赖别的Component,比如 下面这个依赖的是 NetComponent
@UserScope
@Component (modules = SplashModule.class,dependencies = NetComponent.class)
public interface SplashComponent {
    void inject(SplashActivity splashActivity);
}

参考

http://blog.csdn.net/hsk256/article/details/51530667

你可能感兴趣的:(Dagger2初探)