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