Android Dagger2 使用详解(一)基础使用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011033906/article/details/89878572

1. 什么是依赖注入

Dagger 2是Android中比较热门的依赖注入框架,什么是依赖注入呢? 维基百科上是这样描述的:

控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体,将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中.

通俗的来讲呢,就是一个类中需要依赖其他对象时,不需要你亲自为那些需要依赖的对象赋值,为那些对象赋值的操作交给了IOC框架.

eg:当我们在一个类的构造函数中通过参数引入另一个类的对象,或者通过set方法设置一个类的对象其实就是使用的依赖注入

//简单的依赖注入,构造方法或者set()方法都属于依赖注入
public class ClassA {
    ClassB classB;
    public void ClassA(ClassB b) {
        classB = b;
    }
}

Dragger2 使用方式,在 modulebuild.gradle 中添加如下代码:


android {
    ...
    //添加如下配置
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

    annotationProcessor 'com.google.dagger:dagger-compiler:2.22.1'
    // if you use the support libraries
    implementation 'com.google.dagger:dagger-android-support:2.22.1'
    implementation 'com.google.dagger:dagger:2.22.1'

2. 基本使用

import javax.inject.Inject;

public class Student {

    @Inject
    public Student() {
    }
}

编译之后会产生成如下代码:

//...\build\generated\source\apt\debug\com\york\dragger2\bean\Student_Factory.java

import dagger.internal.Factory;

public final class Student_Factory implements Factory<Student> {
  private static final Student_Factory INSTANCE = new Student_Factory();

  @Override
  public Student get() {
    return new Student();
  }

  public static Student_Factory create() {
    return INSTANCE;
  }

  public static Student newInstance() {
    return new Student();
  }
}


通过 @Inject 注解了一个类的构造方法后,可以让编译器帮助我们产生一个对应的 Factory 类,通过这个工厂类我们可以通过简单的 get() 方法获取到 Student 对象!

2.1 创建一个Activity 调用Student

public class MainActivity extends AppCompatActivity {

    @BindView(R.id.btn)
    Button btn;

    @Inject
    User mUser;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
    }

    @OnClick(R.id.btn)
    void btnClicked(){
        System.out.println("======================");
        btn.setText(mUser.toString());
    }
}

直接运行代码,并点击Button,很遗憾,直接报空指针异常。

显然,和平常使用的结果一样,@Inject 并没有帮助我们初始化对应的 Student 对象,或者说,我们的 Activity 并没有使用刚才我们看到的 Student_Factory 类,不过也可以理解,我们并没有建立ActivityStudent_Factory 类之间的关系嘛。

2.2 曲线救国,Component接口

我们接下来创建一个Module类以及一个Component接口:

import dagger.Component;

@Component(modules = SimpleModule.class)
public interface SimpleComponent {
    void inject(MainActivity activity);
}

import dagger.Module;

@Module
public class SimpleModule {

    private MainActivity activity;

    public SimpleModule(MainActivity activity) {
        this.activity = activity;
    }
}

突然出现的这两个类可以称得上是莫名其妙,因为我们从代码上来看并不知道这对于Student和Activity之间关系有什么实质性的进展,但假如我们这时在Activty中添加这一段代码:

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

        ButterKnife.bind(this);

		//Here
        DaggerSimpleComponent.builder()
                .simpleModule(new SimpleModule(this))
                .build()
                .inject(this);
    }

再次点击就可以正常运行代码了。显然,被 @InjectStudent 类被成功依赖注入到了 Activity中,我们接下来就可以肆无忌惮使用这个 Student 对象了!

3. Module 和 Component 的意义

我们可以暂时这样理解 Module,它的作用就好像是快递的箱子,里面装载的是我们想要的商品,我们在 Module 中放入什么商品,快递员 Component 将箱子送到我们家(Activity 容器),我们就可以直接使用里面的商品啦!

为了展示 Module 的作用,我们重写 Student 类,取消了 @Inject 注解:

public class Student {

    public Student() {
    }

}

Module 中添加这样一段代码:

@Module
public class SimpleModule {

    private SimpleModule activity;

    public SimpleModule (MainActivity activity) {
        this.activity = activity;
    }
    //下面为新增代码:
    @Provides
    Student provideStudent(){
        return new Student();
    }
}

然后 Component 不变,Activity 中仍然是这样:

DaggerSimpleComponent.builder()
                .simpleModule(new SimpleModule(this))
                .build()
                .inject(this);

然后运行,我们发现,仍然可以点击使用 Student 对象!

原因很简单,虽然 @Inject 注解取消了,但是我们已经在快递箱子(Module)中通过 @Providers放入了一个 Student对象,然后让快递员(Component)送到了家中(Activity),我们当然可以使用Student对象了!

4. 小结

经过简单的使用 Dagger2,我们已经可以基本有了以下了解:

  • @Inject: 注入,被注解的构造方法会自动编译生成一个 Factory 工厂类提供该类对象。

  • @Component: 注入器,类似快递员,作用是将产生的对象注入到需要对象的容器中,供容器使用。

  • @Module: 模块,类似快递箱子,在 Component 接口中通过 @Component(modules = xxxx.class), 将容器需要的商品封装起来,统一交给快递员(Component),让快递员统一送到目标容器中。

参考链接

猜你喜欢

转载自blog.csdn.net/u011033906/article/details/89878572
今日推荐