HTML5技术

Android -- 带你从源码角度领悟Dagger2入门到放弃(一) - 阿呆哥哥(2)

字号+ 作者:H5之家 来源:H5之家 2017-04-21 11:02 我要评论( )

这时候可能有同学又有疑问了,DaggerTeacherComponent这个类怎么报错啊 ,其实这个类是编译时产生的类大家不用慌,把代码写完了crtl+F9编译一下就可以了,但是!!!这里DaggerTeacherComponent的书写方法是Dagger

  这时候可能有同学又有疑问了,DaggerTeacherComponent这个类怎么报错啊 ,其实这个类是编译时产生的类大家不用慌,把代码写完了crtl+F9编译一下就可以了,但是!!!这里DaggerTeacherComponent的书写方法是Dagger加上你前面自定义的Component接口类的类名,一定要注意,不然很多同学都会在这翻车(我曾经在这儿翻出无数次),然后再说一下我们上一个问题 TeacherComponent 中的inject方法是固定方法吗?很明显这里调用的是inject(this);所以不是固定方法,只不过你Component接口类写成injectA(Teacher teacher),那么你这里调用的方法就是injectA(this)

  ok,上面这些都写好了,我们在Teacher类中添加测试类来测试测试

public class Teacher { //想持有学生对象 @Inject Student student; public Teacher() { DaggerTeacherComponent.builder().build().injectA(this); } public void teacher() { student.startLessons(); } public static void main(String[] args) { new Teacher().teacher(); } }

  看一下打印效果

Student create!!! 开始上课了

3,源码分析

  ok,没什么问题,那我们现在只是停留在会用的阶段,底层我们的源码到底是怎么吧我们的对象创建出来的,还有怎么将我们的对象设置到需要它的地方呢,不要慌,老司机现在就带你来看看源码是什么实现的。这里的源码很简单,一共涉及到三个类,都是我们运行时生成的DaggerTeacherComponent、Teacher_MembersInjector、Student_Factory。

  先来看看DaggerTeacherComponent,按照字面意思这是我们Teacher的桥梁类,源码如下:

package com.qianmo.rxjavatext; import dagger.MembersInjector; import javax.annotation.Generated; @Generated( value = "dagger.internal.codegen.ComponentProcessor", comments = "https://google.github.io/dagger" ) public final class DaggerTeacherComponent implements TeacherComponent { private MembersInjector<Teacher> teacherMembersInjector; private DaggerTeacherComponent(Builder builder) { assert builder != null; initialize(builder); } public static Builder builder() { return new Builder(); } public static TeacherComponent create() { return builder().build(); } @SuppressWarnings("unchecked") private void initialize(final Builder builder) { this.teacherMembersInjector = Teacher_MembersInjector.create(Student_Factory.create()); } @Override public void injectA(Teacher teacher) { teacherMembersInjector.injectMembers(teacher); } public static final class Builder { private Builder() {} public TeacherComponent build() { return new DaggerTeacherComponent(this); } } }

  我们首先来看我们之前的调用方法如下

DaggerTeacherComponent.builder().build().injectA(this);

  首先看一下DaggerTeacherComponent.builder()方法,我们从源码中可以看到DaggerTeacherComponent.builder()调用生成了一个Builder 对象,我们继续代用builder.builder()方法,而我们的build类中代码如下(这里再次吐槽博客园的编辑器,在线编辑的时候无法显示引用代码的行号,这样我们就没法通过行号来解释每一行代码的意思,而必须要重写贴一次代码,操蛋!!!):

public static final class Builder { private Builder() {} public TeacherComponent build() { return new DaggerTeacherComponent(this); } }

  “new DaggerTeacherComponent(this);” 看到没,实际上是调用我们的DaggerTeacherComponent对象,而我们的DaggerTeacherComponent构造函数是调用的initialize()方法,看一下方法里面具体代码

@SuppressWarnings("unchecked") private void initialize(final Builder builder) { this.teacherMembersInjector = Teacher_MembersInjector.create(Student_Factory.create()); }

  这时候出现了Teacher_MembersInjector、Student_Factory类,我们先不要管,继续往下看,上面我们调用完builder.builder()方法方法之后,再调用injectA(this)的方法,具体代码如下:

@Override public void injectA(Teacher teacher) { teacherMembersInjector.injectMembers(teacher); }

  呃,这里我们又看到Teacher_MembersInjector这个类对象了,所以这时候看看我们Teacher_MembersInjector的源码了,我们上面一共在两个地方使用了Teacher_MembersInjector,一个是.create方法,一个是injectMember方法,所以我们主要要留心源码里面这两个类,具体源码如下:

package com.qianmo.rxjavatext; import dagger.MembersInjector; import javax.annotation.Generated; import javax.inject.Provider; @Generated( value = "dagger.internal.codegen.ComponentProcessor", comments = "https://google.github.io/dagger" ) public final class Teacher_MembersInjector implements MembersInjector<Teacher> { private final Provider<Student> studentProvider; public Teacher_MembersInjector(Provider<Student> studentProvider) { assert studentProvider != null; this.studentProvider = studentProvider; } public static MembersInjector<Teacher> create(Provider<Student> studentProvider) { return new Teacher_MembersInjector(studentProvider); } @Override public void injectMembers(Teacher instance) { if (instance == null) { throw new NullPointerException("Cannot inject members into a null reference"); } instance.student = studentProvider.get(); } public static void injectStudent(Teacher instance, Provider<Student> studentProvider) { instance.student = studentProvider.get(); } }

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • Android 代码库(自定义一套 Dialog通用提示框 ) - 小小情意

    Android 代码库(自定义一套 Dialog通用提示框 ) - 小小情意

    2017-04-21 11:01

  • ASP.NET Core MVC 源码学习:详解 Action 的激活 - Savorboard

    ASP.NET Core MVC 源码学习:详解 Action 的激活 - Savorboard

    2017-04-14 13:04

  • 程序员带你一步步分析AI如何玩FlappyBird - yhthu

    程序员带你一步步分析AI如何玩FlappyBird - yhthu

    2017-04-13 09:03

  • 车大棒浅谈jQuery源码(二) - 车大棒

    车大棒浅谈jQuery源码(二) - 车大棒

    2017-04-02 10:07

网友点评
r