dagger.android 源码

https://www.jianshu.com/p/b25a67ccf53b
Demo

application类
    class BalaApp: Application(),HasActivityInjector {
    
        @Inject
        lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector<Activity>
    
        override fun activityInjector(): AndroidInjector<Activity> {
            return dispatchingAndroidInjector
        }
    
        override fun onCreate() {
            super.onCreate()
    
            DaggerAppComponent.create().inject(this)
        }
    }
AppComponent
    @Component(modules = [AndroidInjectionModule::class, AndroidSupportInjectionModule::class, MainModule::class, SecondModule::class])
    interface AppComponent {
        fun inject(application: BalaApp)
    }
BaseActivity
    open class BaseActivity: AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            AndroidInjection.inject(this)
            super.onCreate(savedInstanceState)
        }
    }
MainActivity
    class MainActivity : BaseActivity() {
    
        @Inject
        lateinit var claName:String
        @Inject
        lateinit var student: Student
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
            Log.d("eee=main","-------$claName----------$student")
        }
    
        fun mainClick(view: View){
            when(view.id){
                R.id.btn_second->startActivity(Intent(this,SecondActivity::class.java))
            }
        }
    }
MainModule
    @Module(subcomponents = [MainSubcomponent::class])
    abstract class MainModule {
    
        @Binds
        @IntoMap
        @ActivityKey(MainActivity::class)
        abstract fun bindMainActivityInjectorFactory(builder: MainSubcomponent.Builder): AndroidInjector.Factory<out Activity>
    
    }
MainSubcomponent
    @Subcomponent(modules = [AndroidInjectionModule::class, MainSubcomponent.SubModule::class])
    interface MainSubcomponent : AndroidInjector<MainActivity> {
    
        @Subcomponent.Builder
        abstract class Builder : AndroidInjector.Builder<MainActivity>() {
    
        }
    
        @Module
        class SubModule {
            @Provides
            fun provideName(): String {
                return MainActivity::class.java.name
            }
            @Provides
        fun provideStudent():Student{
                return Student()
            }
        }
    
    }
SecondActivity
    class SecondActivity: BaseActivity() {
    
        @Inject
        lateinit var className:String
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_second)
    
            Log.d("eee=second","-------$className")
        }
    }
SecondComponent
    @Subcomponent(modules = [AndroidInjectionModule::class, SecondComponent.SubModule::class])
    interface SecondComponent : AndroidInjector<SecondActivity> {
        @Subcomponent.Builder
        abstract class Builder : AndroidInjector.Builder<SecondActivity>() {
        }
    
        @Module
        class SubModule {
            @Provides
            fun provideName(): String {
                return SecondActivity::class.java.name
            }
        }
    
    }
SecondModule
    @Module(subcomponents = [SecondComponent::class])
    abstract class SecondModule {
    
        @Binds
        @IntoMap
        @ActivityKey(SecondActivity::class)
        abstract fun bindSecondActivityInjectorFactory(builder: SecondComponent.Builder): AndroidInjector.Factory<out Activity>
    }
Student
    class Student
module的作用
  • 把对应的Component.Builder跟AndroidInjector.Factory绑定起来。
  • 真正提供数据是在Component中的子module中
DaggerAppComponent.create做了哪些操作
  • 把每个Subcomponent.Builder封装在Provider中。然后以键值对的方式存储在map集合中

    private void initialize(final Builder builder) {
      this.mainSubcomponentBuilderProvider =
          new Provider<MainSubcomponent.Builder>() {
            @Override
            public MainSubcomponent.Builder get() {
              return new MainSubcomponentBuilder();
            }
          };
      this.secondComponentBuilderProvider =
          new Provider<SecondComponent.Builder>() {
            @Override
            public SecondComponent.Builder get() {
              return new SecondComponentBuilder();
            }
          };
    }
    
      private Map<Class<? extends Activity>, Provider<AndroidInjector.Factory<? extends Activity>>>
        getMapOfClassOfAndProviderOfFactoryOf() {
      return MapBuilder
          .<Class<? extends Activity>, Provider<AndroidInjector.Factory<? extends Activity>>>
              newMapBuilder(2)
          .put(MainActivity.class, (Provider) mainSubcomponentBuilderProvider)
          .put(SecondActivity.class, (Provider) secondComponentBuilderProvider)
          .build();
    }
    
  • 在initialize中可以看到,继承匿名Provider内部类,重写了一个get方法。里面new了一个SubcomponentBuilder类,这里就拿到了对应component中子module对象

  • 然后再new一个SubcomponentImpl实现类,里面就进行传统了inject、module、component的操作。

  • 以Main为例,看下MainSubcomponentBuilder的代码

    private final class MainSubcomponentBuilder extends MainSubcomponent.Builder {
      private MainSubcomponent.SubModule subModule;
    
      private MainActivity seedInstance;
    
      @Override
      public MainSubcomponent build() {
        if (subModule == null) {
          this.subModule = new MainSubcomponent.SubModule();
        }
        if (seedInstance == null) {
          throw new IllegalStateException(MainActivity.class.getCanonicalName() + " must be set");
        }
        return new MainSubcomponentImpl(this);
      }
    
      @Override
      public void seedInstance(MainActivity arg0) {
        this.seedInstance = Preconditions.checkNotNull(arg0);
      }
    }
    
  • SubcomponentImpl实现类的代码

    private final class MainSubcomponentImpl implements MainSubcomponent {
      private MainSubcomponent.SubModule subModule;
    
      private MainSubcomponentImpl(MainSubcomponentBuilder builder) {
        initialize(builder);
      }
    
      @SuppressWarnings("unchecked")
      private void initialize(final MainSubcomponentBuilder builder) {
        this.subModule = builder.subModule;
      }
    
      @Override
      public void inject(MainActivity arg0) {
        injectMainActivity(arg0);
      }
    
      private MainActivity injectMainActivity(MainActivity instance) {
        MainActivity_MembersInjector.injectClaName(
            instance, MainSubcomponent_SubModule_ProvideNameFactory.proxyProvideName(subModule));
        MainActivity_MembersInjector.injectStudent(
            instance,
            MainSubcomponent_SubModule_ProvideStudentFactory.proxyProvideStudent(subModule));
        return instance;
      }
    }
    
  • 通过上述可以看到,map集合中存储了所有的数据,就看后续是怎么从map集合中拿出来使用了。

DaggerAppComponent.create().inject(this)做了哪些操作
  • 把上面说的存储了所有数据的map集合再封装到了applic类中的dispatchingAndroidInjector中

    private BalaApp injectBalaApp(BalaApp instance) {
      BalaApp_MembersInjector.injectDispatchingAndroidInjector(
          instance, getDispatchingAndroidInjectorOfActivity());
      return instance;
    }
    
BaseActivity中的AndroidInjection.inject(this)。以MainActivity为例
  public static void inject(Activity activity) {
    checkNotNull(activity, "activity");
    Application application = activity.getApplication();
    if (!(application instanceof HasActivityInjector)) {
      throw new RuntimeException(
          String.format(
              "%s does not implement %s",
              application.getClass().getCanonicalName(),
              HasActivityInjector.class.getCanonicalName()));
    }

    AndroidInjector<Activity> activityInjector =
        ((HasActivityInjector) application).activityInjector();
    checkNotNull(activityInjector, "%s.activityInjector() returned null", application.getClass());

    activityInjector.inject(activity);
  }
  • activityInjector就是application中的dispatchingAndroidInjector,因为DispatchingAndroidInjector是继承AndroidInjector的。所以inject调用的是dispatchingAndroidInjector的inject。看下做了什么操作。

    public boolean maybeInject(T instance) {
      Provider<AndroidInjector.Factory<? extends T>> factoryProvider =
          injectorFactories.get(instance.getClass().getName());
      if (factoryProvider == null) {
        return false;
      }
    
      @SuppressWarnings("unchecked")
      AndroidInjector.Factory<T> factory = (AndroidInjector.Factory<T>) factoryProvider.get();
      try {
        AndroidInjector<T> injector =
            checkNotNull(
                factory.create(instance), "%s.create(I) should not return null.", factory.getClass());
    
        injector.inject(instance);
        return true;
      } catch (ClassCastException e) {
        throw new InvalidInjectorBindingException(
            String.format(
                "%s does not implement AndroidInjector.Factory<%s>",
                factory.getClass().getCanonicalName(), instance.getClass().getCanonicalName()),
            e);
      }
    }
    
  • 可以看到factoryProvider就是从map集合中拿到了对应的provider,然后调用get方法,就是执行了DaggerAPPComponent的initialize中的匿名内部类的get方法。

  • 以mainActivity为例,get方法就是拿到了MainSubcomponentBuilder对象,然后调用create方法,因为MainSubcomponentBuilder继承MainSubcomponent.Builder,然后MainSubcomponent.Builder又是继承AndroidInjector.Builder。所以这里的create方法调用的是seedInstance

    abstract class Builder<T> implements AndroidInjector.Factory<T> {
      @Override
      public final AndroidInjector<T> create(T instance) {
        seedInstance(instance);
        return build();
      }
    
  • 也就是在MainSubcomponentBuilder重写的seedInstance

      @Override
      public void seedInstance(MainActivity arg0) {
        this.seedInstance = Preconditions.checkNotNull(arg0);
      }
    
  • 然后执行的是maybeInject中的injector.inject(instance);上面可以看到调用seedInstance后返回的是执行build方法后返回的MainSubcomponentImpl对象。

      @Override
      public MainSubcomponent build() {
        if (subModule == null) {
          this.subModule = new MainSubcomponent.SubModule();
        }
        if (seedInstance == null) {
          throw new IllegalStateException(MainActivity.class.getCanonicalName() + " must be set");
        }
        return new MainSubcomponentImpl(this);
      }
    
  • 所以这个inject就是执行MainSubcomponentBuilder中重写的inject方法,也就是最后的赋值操作了。

  • 此时上面的所有流程也就串通了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值