前言
在上一篇文章中 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<Student> {
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<Daggertest1Activity> {
private final Provider<Student> mStudentProvider;
public Daggertest1Activity_MembersInjector(Provider<Student> mStudentProvider) {
this.mStudentProvider = mStudentProvider;
}
public static MembersInjector<Daggertest1Activity> create(Provider<Student> 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<Student> mStudentProvider; 這個應該就是在Student_Factory里提供的工廠類。
不信看一下
public interface Factory<T> extends Provider<T> {
}
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。