dagger.android 源码

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方法,也就是最后的赋值操作了。
  • 此时上面的所有流程也就串通了

推荐阅读更多精彩内容