Android開發之Dagger2--源碼角度分析inject過程(二)

前言

在上一篇文章中 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,我們一步步來。

    1. 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。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容