前言
在上一篇文章中 Android开发之Dagger2的基本使用(一),主要是在项目了里导入了Dagger2,并注入成功,实现了基本的功能。在上一篇文章的末尾也提出了几个问题
- 添加inject后,通过编译生成的DaggerMainComponent类来导入,说明编译以后生成了一些类,那到底生成了什么类呢。
- Module和Component又是什么,该怎么里理解
在这篇文章后里将一一讨论。
引入Dagger2后生成的类
对项目进行编译以后,我们打开app的build目录,我的是在app\build\generated\source\apt\debug\com\jackson\daggertest下,可以看到引入Dagger2后生成的类,一共有三个,分别是 Student_Factory.java,DaggerMainComponent.java,Daggertest1Activity_MembersInjector.java,我们一步步来。
-
- Student_Factory.java,对Student的构造方法用@Inject注解后编译生成
public final class Student_Factory implements Factory {
private static final Student_Factory INSTANCE = new Student_Factory();
@Override
public Student get() {
return new Student();
}
public static Student_Factory create() {
return INSTANCE;
}
}
不难看出这实际上是一个工厂类,create()方法提供工厂实例,get()获取Studnet的对象。也就是说我们对一个类的构造方法用@Inject注解后,会生成一个提供该类实例的类。
- 2 DaggerMainComponent.java
源码如下:
public final class DaggerMainComponent implements MainComponent {
private DaggerMainComponent(Builder builder) {}
public static Builder builder() {
return new Builder();
}
public static MainComponent create() {
return new Builder().build();
}
@Override
public void inject(Daggertest1Activity daggertest1Activity) {
injectDaggertest1Activity(daggertest1Activity);
}
private Daggertest1Activity injectDaggertest1Activity(Daggertest1Activity instance) {
Daggertest1Activity_MembersInjector.injectMStudent(instance, new Student());
return instance;
}
public static final class Builder {
private Builder() {}
public MainComponent build() {
return new DaggerMainComponent(this);
}
/**
* @deprecated This module is declared, but an instance is not used in the component. This
* method is a no-op. For more, see https://google.github.io/dagger/unused-modules.
*/
@Deprecated
public Builder mainModule(MainModule mainModule) {
Preconditions.checkNotNull(mainModule);
return this;
}
}
}
很明显,这是我们在Activity里调用的,类名很简单,就是Dagger+Component的名字,Activity里的调用代码如下:
DaggerMainComponent.builder()
.mainModule(new MainModule())
.build()
.inject(this);
结合源码可以看到,DaggerMainComponent是通过Builder模式新建了一个DaggerMainComponent的对象,当DaggerMainComponent的对象执行inject()方法时,会最终执行Daggertest1Activity_MembersInjector的injectMStudent()方法,参数为this,既当前的Activity的实例,我们继续往下看。
3 Daggertest1Activity_MembersInjector.java
public final class Daggertest1Activity_MembersInjector
implements MembersInjector {
private final Provider mStudentProvider;
public Daggertest1Activity_MembersInjector(Provider mStudentProvider) {
this.mStudentProvider = mStudentProvider;
}
public static MembersInjector create(Provider mStudentProvider) {
return new Daggertest1Activity_MembersInjector(mStudentProvider);
}
@Override
public void injectMembers(Daggertest1Activity instance) {
injectMStudent(instance, mStudentProvider.get());
}
public static void injectMStudent(Daggertest1Activity instance, Student mStudent) {
instance.mStudent = mStudent;
}
}
上面提到,当在Activity执行injec方法时,会最终执行到这个类的injectMStudent()方法,其中传递过来了Activity的实例,那么是怎么将Activity的mStudent和Student_Factory提供的Student实例联系起来呢。
public static void injectMStudent(Daggertest1Activity instance, Student mStudent) {
instance.mStudent = mStudent;
}
通过这个方法,我们可以看到,传递过来的instance里的mStudnet被赋值了一个mStudent对象,那么我们猜测,这个mStudent就是从Student_Factory传递过来的,到底是不是呢,我们继续验证。
@Override
public void injectMembers(Daggertest1Activity instance) {
injectMStudent(instance, mStudentProvider.get());
}
injectMStudent()方法在这个地方调用,其中传递过来的是mStudentProvider.get(),在看一下这个mStudentProvider的定义,private final Provider
不信看一下
public interface Factory extends Provider {
}
Factory的父类正是Provider,mStudentProvider.get()就是获取的是Student_Factory的Student对象,然后和instnce里的对象进行赋值;
@Override
public Student get() {
return new Student();
}
综上,通过生成的类,我们一步步追踪到了,当对一个类吃的构造方法使用@Inject注解
@Inject
public Student(){
}
在Activity里,执行注入操作后
@Inject
Student mStudent; // 注入Studnet的实例
DaggerMainComponent.builder()
.mainModule(new MainModule())
.build()
.inject(this);
Activity里的mStudent是怎么和Student的实例联系起来的。
总结起来就是一下几点:
- 1 通过工厂方法提供类的实例
- 2 生成Dagger+Component名字的类,通过Builder模式提供该类的实例
- 3 执行inject方法时建立实例之间的联系
下篇文章再讨论 Module和Component。