Dagger2 的一个原理理解方向


说在前面:别人都是从两个端出发开始连线,而我是从线开始寻找连接的端。


本文仅提供一个思考的方向,是我本人对Dagger2的理解,如若错误请留言指正,3Q。并且本文打算私藏,由于同桌好友需要阅读,姑且公开了吧。

阅读本文前需要先阅读 littleKang 的文章 http://www.jianshu.com/p/39d1df6c877d

1: Component

首先确定我们的目的:为了解耦,我们使用依赖注入的方式,去分离变量的声明和实例化。若分离了实例化,则实例化需要打参数必定是通过某种方式去获得。而下面我要讲的就是这个参数(this)的传递过程。

Component作为连接目标和源的桥梁,所以在Component必定包含了目标和源的引用。所以看Google为我们生成的代码(大部分是工厂类),没错我们直接从这部分代码开始。

// Ours
@Component(modules = MainModule.class)
public interface MainComponent {
    void inject(MainActivity activity);
}
// Google
public final class DaggerMainComponent implements MainComponent {
  private Provider provideMainViewProvider;

  private Provider mainPresenterProvider;

  private MembersInjector mainActivityMembersInjector;

  private DaggerMainComponent(Builder builder) {
    assert builder != null;
    initialize(builder);
  }

  public static Builder builder() {
    return new Builder();
  }

  @SuppressWarnings("unchecked")
  private void initialize(final Builder builder) {

    this.provideMainViewProvider = MainModule_ProvideMainViewFactory.create(builder.mainModule);

    this.mainPresenterProvider = MainPresenter_Factory.create(provideMainViewProvider);

    this.mainActivityMembersInjector = MainActivity_MembersInjector.create(mainPresenterProvider);
  }

  @Override
  public void inject(MainActivity activity) {
    mainActivityMembersInjector.injectMembers(activity);
  }

  public static final class Builder {
    private MainModule mainModule;

    private Builder() {}

    public MainComponent build() {
      if (mainModule == null) {
        throw new IllegalStateException(MainModule.class.getCanonicalName() + " must be set");
      }
      return new DaggerMainComponent(this);
    }

    public Builder mainModule(MainModule mainModule) {
      this.mainModule = Preconditions.checkNotNull(mainModule);
      return this;
    }
  }
}

根据

DaggerMainComponent.builder()
                .mainModule(new MainModule(this))
                .build()
                .inject(this);

的调用顺序看Google生成的代码,

  • DaggerMainComponent 调用静态方法builder()返回内部静态类Builder的对象
  • 接着调用的是Builder的方法mainModule()去实例化属性mainModule,而调用该方法时this参数传递到了Module
  • 接着调用build()方法,使用静态内部类完成DaggerMainComponent的创建(直到这里可以发现Component已经连接到了Module),值得一说的就是在new DaggerMainComponent时调用了initialize()
  • initialize()中,初始化了三个属性(三个工厂类对象),这里需要注意到的是参数,MainModule_ProvideMainViewFactory的参数是builder,这本类中已经完成builder的初始化;接着下面的两个属性的初始化都是以它上一个的对象作为参数,而且都是实例化完毕的!(直到这里知道,这里没有哪个是没有初始化的, That is good!)
  • 完成了DaggerMainComponent的创建就可以使用inject()方法,该方法中调用了injectMembers()方法,注入activity参数,而改参数是MainActivity给予的,这在理解上完全没问题的。(直到这里可以看到DaggerMainComponent连接MainActivity的苗头了,好像这里没看出连接了啥,嗯,确实是,后面会接着说这个问题)

2: Module

1.中已经知道了Module的工厂类的create()方法被调用,已经实现了初始化,那么我们下面直接从create()方法开始看

// Ours
@Module
public class MainModule {
    private final MainContract.View mView;

    public MainModule(MainContract.View view) {
        mView = view;
    }

    @Provides
    MainContract.View provideMainView() {
        return mView;
   }   
}
// Google
public final class MainModule_ProvideMainViewFactory implements Factory {
  private final MainModule module;

  public MainModule_ProvideMainViewFactory(MainModule module) {
    assert module != null;
    this.module = module;
  }

  @Override
  public MainContract.View get() {
    return Preconditions.checkNotNull(
        module.provideMainView(), "Cannot return null from a non-@Nullable @Provides method");
  }

  public static Factory create(MainModule module) {
    return new MainModule_ProvideMainViewFactory(module);
  }
}
  • create()方法调用了改工厂类的初始化方法,而参数module1.中调用该工厂类的ceate()方法时给予的,所以不要再考虑谁给的参数用来实例化
  • 实例化好该工厂类之后,将module.provideMainView()返回,之后就可以供Factory的对象获取对象mView

3: Presenter(或者是我们自己创建的类,供宿主(MainActivity)使用的类)

这里是一样的,在1.中调用了create()方法,直接从该方法开始分析

// Ours
public class MainPresenter {
    MainContract.View mView;
    @Inject
    MainPresenter(MainContract.View view) {
        mView = view;
    }
 }
// Google
public final class MainPresenter_Factory implements Factory {
  private final Provider viewProvider;

  public MainPresenter_Factory(Provider viewProvider) {
    assert viewProvider != null;
    this.viewProvider = viewProvider;
  }

  @Override
  public MainPresenter get() {
    return new MainPresenter(viewProvider.get());
  }

  public static Factory create(Provider viewProvider) {
    return new MainPresenter_Factory(viewProvider);
  }
}
  • create()方法中实例化并返回该工厂类的对象,而该类中的get()方法直接返回我们需要依赖的MainPresenter对象,而实例化所需要的参数在create()方法给出!(还没有思路的话就绕着这个参数返回阅读)
  • 直到这里,我们可以了解这么一个情况,从MainActivity中给予的参数经过一系列的传递,最后传到了MainPresenter()中,那么也就是说,我们直接调用这里的get()方法便可以直接获取MainPresenter类的实例!
  • 那么好,经过一系列的传递后该对象得到了初始化有了,然而怎么讲这么实例传回MainActivity

4: MembersInjector

在这里我们可以返回到1.中的最后的问题:连接!

终于到这一步了,看到前面参数一层一层传递,初始化了各种的工厂类,等着你一个get()的调用,我就给你初始化好的实例了!还是照样,代码搬上来说话。

public final class MainActivity_MembersInjector implements MembersInjector {
  private final Provider mainPresenterProvider;

  public MainActivity_MembersInjector(Provider mainPresenterProvider) {
    assert mainPresenterProvider != null;
    this.mainPresenterProvider = mainPresenterProvider;
  }

  public static MembersInjector create(
      Provider mainPresenterProvider) {
    return new MainActivity_MembersInjector(mainPresenterProvider);
  }

  @Override
  public void injectMembers(MainActivity instance) {
    if (instance == null) {
      throw new NullPointerException("Cannot inject members into a null reference");
    }
    instance.mainPresenter = mainPresenterProvider.get();
  }

  public static void injectMainPresenter(
      MainActivity instance, Provider mainPresenterProvider) {
    instance.mainPresenter = mainPresenterProvider.get();
  }
}

在这里我还得提示一点就是1.中的这个方法重写里面的调用

 @Override
  public void inject(MainActivity activity) {
    mainActivityMembersInjector.injectMembers(activity);
  }
  • 在这里我们还是先看看已经在1.中初始化了的MainActivity_MembersInjector对象的create()方法干了啥:调用构造方法,并直接返回该工厂类的对象!(这会儿,看看1. 中调用 injectMembers(),或许你会激动点啥的...)
  • 对应的,我们直接找injectMembers()方法,该方法的实现就在这个工厂类里边儿,而且我们有点激动的发现,我们传进来的宿主MainActivity的对象(引用)的属性mainPresenter得到了赋值(初始化!),而等号右边的就是已经准备好了提供Present实例的get()方法!
  • 知道这里可以想到了,Component是连接两头的关键之处

说在最后:本文只是提供一个理解方向,更多的内容本人还在学习当中


你可能感兴趣的:(Dagger2 的一个原理理解方向)