dagger.android 源码
2018-11-05 本文已影响5人
喂_balabala
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方法,也就是最后的赋值操作了。
- 此时上面的所有流程也就串通了