本系列所有文章:
Android 神兵利器Dagger2使用詳解(一)基礎(chǔ)使用
Android 神兵利器Dagger2使用詳解(二)Module&Component源碼分析
Android 神兵利器Dagger2使用詳解(三)MVP架構(gòu)下的使用
Android 神兵利器Dagger2使用詳解(四)Scope注解的使用及源碼分析
告別Dagger2模板代碼:DaggerAndroid使用詳解
告別Dagger2模板代碼:DaggerAndroid原理解析
該系列首發(fā)于我的CSDN專欄 :
Android開發(fā):Dagger2詳解
概述
距離我的上一篇文章發(fā)布以來频轿,有幸收獲了一些朋友的認(rèn)可,我很開心。
在上一篇文章中,我簡單敘述了Dagger2這個(gè)庫目前在Android開發(fā)中的一些短板切诀,為什么我們學(xué)習(xí)Dagger-Android這個(gè)拓展庫齿风,以及如何使用這個(gè)拓展庫。
今天我們進(jìn)行代碼分析饿序,看看Dagger-Android是如何基于Dagger2實(shí)現(xiàn)一行代碼實(shí)現(xiàn)所有同類組件依賴注入的黑界。
閱讀本文也許您需要準(zhǔn)備的
- 本文可能需要您對Dagger2有一定的了解管嬉,包括它內(nèi)部模板代碼生成的一些邏輯。
核心代碼
書承上文朗鸠,我們知道蚯撩,我們實(shí)現(xiàn)依賴注入的代碼主要為以下兩行:
public class MyApplication extends Application implements HasActivityInjector {
@Inject
DispatchingAndroidInjector<Activity> dispatchingAndroidInjector;
@Override
public void onCreate() {
super.onCreate();
//1.Application級的依賴注入
DaggerMyAppComponent.create().inject(this);
}
@Override
public AndroidInjector<Activity> activityInjector() {
return dispatchingAndroidInjector;
}
}
public class BaseActivity extends AppCompatActivity{
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
//2.Activity級的依賴注入
AndroidInjection.inject(this);
super.onCreate(savedInstanceState);
}
}
拋開這兩行,也許我們還有更多疑問:
- 1.MyApplication中的dispatchingAndroidInjector成員是干嘛的
- 2.MyApplication實(shí)現(xiàn)的HasActivityInjector接口和實(shí)現(xiàn)的activityInjector()方法又是干嘛的
- 3.為什么這樣2行依賴注入代碼烛占,就能代替之前我們每個(gè)Activity都需要寫的模板代碼呢:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// DO THIS FIRST. Otherwise frombulator might be null!
((SomeApplicationBaseType) getContext().getApplicationContext())
.getApplicationComponent()
.newActivityComponentBuilder()
.activity(this)
.build()
.inject(this);
// ... now you can write the exciting code
}
直接公布結(jié)論:
這三張圖描述了很多東西胎挎,我們不需要先去看懂它,我們會隨著我們的步驟扰楼,一步步分析透徹它呀癣,撥開云霧見晴天。弦赖、
首先我們分析Application中的這行代碼:
DaggerMyAppComponent.create().inject(this);
一、DaggerMyAppComponent.create()原理
我們先點(diǎn)開create()方法浦辨,可以看到蹬竖,無非是初始化了一個(gè)DaggerMyAppComponent對象,然后執(zhí)行了initialize()方法
public static MyAppComponent create() {
return new Builder().build();
}
public static final class Builder {
private Builder() {
}
public MyAppComponent build() {
return new DaggerMyAppComponent(this);
}
}
private DaggerMyAppComponent(Builder builder) {
assert builder != null;
initialize(builder);
}
我們接著看initialize()方法:
private void initialize(final Builder builder) {
//1
this.mainActivitySubcomponentBuilderProvider =
new dagger.internal.Factory<
AllActivitysModule_ContributeMainActivitytInjector.MainActivitySubcomponent.Builder>() {
@Override
public AllActivitysModule_ContributeMainActivitytInjector.MainActivitySubcomponent.Builder
get() {
return new MainActivitySubcomponentBuilder();
}
};
this.bindAndroidInjectorFactoryProvider = (Provider) mainActivitySubcomponentBuilderProvider;
this.secondActivitySubcomponentBuilderProvider =
new dagger.internal.Factory<
AllActivitysModule_ContributeSecondActivityInjector.SecondActivitySubcomponent
.Builder>() {
@Override
public AllActivitysModule_ContributeSecondActivityInjector.SecondActivitySubcomponent
.Builder
get() {
return new SecondActivitySubcomponentBuilder();
}
};
this.bindAndroidInjectorFactoryProvider2 = (Provider) secondActivitySubcomponentBuilderProvider;
//2
this.mapOfClassOfAndProviderOfFactoryOfProvider =
MapProviderFactory
.<Class<? extends Activity>, AndroidInjector.Factory<? extends Activity>>builder(2)
.put(MainActivity.class, bindAndroidInjectorFactoryProvider)
.put(SecondActivity.class, bindAndroidInjectorFactoryProvider2)
.build();
//3
this.dispatchingAndroidInjectorProvider =
DispatchingAndroidInjector_Factory.create(mapOfClassOfAndProviderOfFactoryOfProvider);
//4
this.myApplicationMembersInjector =
MyApplication_MembersInjector.create(dispatchingAndroidInjectorProvider);
}
這就有點(diǎn)難受了流酬,代碼很多币厕,我們一步步慢慢分析。
我們不要一次想著把這些代碼徹底讀懂芽腾,我們首先大概對整個(gè)流程有個(gè)了解旦装,之后慢慢拆分代碼不遲:
- 我們可以理解為直接初始化了MainActivitySubcomponentBuilder和SecondActivitySubcomponentBuilder的對象,這個(gè)對象能夠提供一個(gè)對應(yīng)ActivityComponent的實(shí)例化對象摊滔,有了這個(gè)實(shí)例化對象阴绢,我們就能夠?qū)?yīng)的Activity進(jìn)行依賴注入店乐。
- 這個(gè)很明顯了,把所有ActivityComponent的實(shí)例化對象都存儲到一個(gè)Map中呻袭,然后這個(gè)Map通過放入mapOfClassOfAndProviderOfFactoryOfProvider對象中眨八。
- 通過mapOfClassOfAndProviderOfFactoryOfProvider初始化dispatchingAndroidInjectorProvider對象
- 通過dispatchingAndroidInjectorProvider對象初始化myApplicationMembersInjector對象
好的基本差不多了 我們看看每個(gè)步驟都是如何實(shí)現(xiàn)的
第1步詳細(xì)分析
以SecondActivity的這行代碼為例:
this.secondActivitySubcomponentBuilderProvider =
new dagger.internal.Factory< //1.看這行,實(shí)際上是new了一個(gè)能提供SecondActivitySubcomponentBuilder()的Provider
AllActivitysModule_ContributeSecondActivityInjector.SecondActivitySubcomponent
.Builder>() {
@Override
public AllActivitysModule_ContributeSecondActivityInjector.SecondActivitySubcomponent
.Builder
get() {
//2.這個(gè)SecondActivitySubcomponentBuilder能干什么呢
return new SecondActivitySubcomponentBuilder();
}
};
private final class SecondActivitySubcomponentImpl
implements AllActivitysModule_ContributeSecondActivityInjector.SecondActivitySubcomponent {
private MembersInjector<SecondActivity> secondActivityMembersInjector;
//3.我們點(diǎn)開構(gòu)造方法左电,看到實(shí)際是走了initialize(builder);
private SecondActivitySubcomponentImpl(SecondActivitySubcomponentBuilder builder) {
assert builder != null;
initialize(builder);
}
@SuppressWarnings("unchecked")
private void initialize(final SecondActivitySubcomponentBuilder builder) {
//4.實(shí)際上是初始化了一個(gè)SecondActivity_MembersInjector廉侧,這個(gè)Injector能夠?qū)econdActivity所需要的對象提供注入
this.secondActivityMembersInjector =
SecondActivity_MembersInjector.create(SecondActivityModule_ProvideNameFactory.create());
}
@Override
public void inject(SecondActivity arg0) {
//5.我們不難想象,不久后當(dāng)SecondActivity需要依賴注入篓足,一定會執(zhí)行這行代碼進(jìn)行對象注入
secondActivityMembersInjector.injectMembers(arg0);
}
}
看到這里我們明白了段誊,實(shí)際上第一步是ApplicationComponent實(shí)例化了所有的ActivityComponent(就是那個(gè)能提供SecondActivitySubcomponentBuilder()的Provider)
然后每個(gè)ActivityComponent都能提供某個(gè)Activity依賴注入所需要的ActivityMembersInjector。
第2步第3步分析
第2步就很簡單了栈拖,這些ActivityComponent都被放入了一個(gè)Map集合中连舍,該集合又放入了apOfClassOfAndProviderOfFactoryOfProvider中,這個(gè)Provider實(shí)際上也是一個(gè)工廠辱魁,負(fù)責(zé)提供該Map的實(shí)例化
第3步也很好理解拷呆,我們MapProvider工廠交給了就是dispatchingAndroidInjectorProvider去管理结序。
第4步分析:
實(shí)際上我們傳入dispatchingAndroidInjectorProvider做了什么呢?
我們看看MyApplication_MembersInjector對象是干嘛的:
//核心代碼
public final class MyApplication_MembersInjector implements MembersInjector<MyApplication> {
private final Provider<DispatchingAndroidInjector<Activity>> dispatchingAndroidInjectorProvider;
...
...
...
//依賴注入Application!
@Override
public void injectMembers(MyApplication instance) {
instance.dispatchingAndroidInjector = dispatchingAndroidInjectorProvider.get();
}
}
大家可以明白了,原來第四步初始化該對象時(shí)匈仗,會將傳入的dispatchingAndroidInjectorProvider存儲起來,將來用到的時(shí)候?qū)⑵鋵ο笞⑷氲叫枰⑷氲腁pplication中:
public class MyApplication extends Application implements HasActivityInjector {
//就是注入給這個(gè)成員變量辣辫!
@Inject
DispatchingAndroidInjector<Activity> dispatchingAndroidInjector;
//省略其他代碼
...
...
}
整理思路
現(xiàn)在我們再來看一下這張圖蔫骂,相信您已經(jīng)對這張圖有所領(lǐng)會了。
可以看到青灼,Application進(jìn)行初始化時(shí)暴心,僅僅一部DaggerMyAppComponent.create(),就已經(jīng)處理了如此多的事件杂拨,初始化了這么多工廠類专普,等待我們?nèi)フ{(diào)用他們實(shí)現(xiàn)依賴注入了。
二弹沽、DaggerMyAppComponent.create().inject(this)原理
其實(shí)這個(gè)步驟就是確定一下我們上面的對Dagger-Android這個(gè)庫的分析是否是對的檀夹,我們來看這行代碼
public final class DaggerMyAppComponent implements MyAppComponent {
...
...
...
@Override
public void inject(MyApplication application) {
myApplicationMembersInjector.injectMembers(application);
}
}
這就和我們上面第四步的分析吻合了:
//我們剛才分析過的,再看一遍
//核心代碼
public final class MyApplication_MembersInjector implements MembersInjector<MyApplication> {
private final Provider<DispatchingAndroidInjector<Activity>> dispatchingAndroidInjectorProvider;
...
...
...
//依賴注入Application!
@Override
public void injectMembers(MyApplication instance) {
instance.dispatchingAndroidInjector = dispatchingAndroidInjectorProvider.get();
}
}
public class MyApplication extends Application implements HasActivityInjector {
//就是注入給這個(gè)成員變量策橘!
@Inject
DispatchingAndroidInjector<Activity> dispatchingAndroidInjector;
//省略其他代碼
...
...
}
整理思路
可以看到炸渡,這一步實(shí)際上我們做了至關(guān)重要的一步,就是把Application中的這個(gè)不知道是干什么的成員變量進(jìn)行了初始化@鲆选0龆隆!
@Inject
DispatchingAndroidInjector<Activity> dispatchingAndroidInjector;
我們現(xiàn)在知道,這個(gè)dispatchingAndroidInjector中吼畏,實(shí)際擁有一個(gè)Map,Map中有著所有Activity所需依賴注入使用的Component!
可以說督赤,這個(gè)看起來平凡無奇的成員變量,才是我們整個(gè)項(xiàng)目依賴注入的大管家宫仗!
頓悟
相信如果您認(rèn)真一步步看到這里够挂,對于下面的2個(gè)問題,您已經(jīng)有了自己的答案:
- 1.MyApplication中的dispatchingAndroidInjector成員是干嘛的
三藕夫、 AndroidInjection.inject(this)原理
我們在初始化一個(gè)Activity孽糖,必然會調(diào)用BaseActivity中的這行代碼:
AndroidInjection.inject(this)
我們好奇,為什么僅僅在BaseActivity這樣1行依賴注入代碼毅贮,就能代替之前我們每個(gè)Activity都需要寫的模板代碼呢办悟?
答案近在眼前。
public final class AndroidInjection {
...
...
...
public static void inject(Activity activity) {
//核心代碼如下
//1.獲取Application
Application application = activity.getApplication();
//2.通過activityInjector()獲取dispatchingAndroidInjector對象滩褥!
AndroidInjector<Activity> activityInjector =
((HasActivityInjector) application).activityInjector();
//3.dispatchingAndroidInjector依賴注入
activityInjector.inject(activity);
}
}
前兩步毫無技術(shù)含量病蛉,我們繼續(xù)看activityInjector.inject(activity):
我們需要找到真正的activityInjector對象,就是DispatchingAndroidInjector:
public final class DispatchingAndroidInjector<T> implements AndroidInjector<T> {
@Override
public void inject(T instance) { //instance在這里為Activity
//1.執(zhí)行maybeInject()方法
boolean wasInjected = maybeInject(instance);
}
public boolean maybeInject(T instance) { //instance在這里為Activity
//2.獲取對應(yīng)Provider
Provider<AndroidInjector.Factory<? extends T>> factoryProvider =
injectorFactories.get(instance.getClass());
AndroidInjector.Factory<T> factory = (AndroidInjector.Factory<T>) factoryProvider.get();
//3.獲取對應(yīng)的ActivityMembersInjector
AndroidInjector<T> injector =
factory.getClass().getCanonicalName());
//4.注入到對應(yīng)的Activity中
injector.inject(instance);
}
}
整理思路
可以看到瑰煎,這一步實(shí)際上我們只是取得Application中的大管家dispatchingAndroidInjector铺然,通過它取得了對應(yīng)Activity的Inject實(shí)例,并進(jìn)行依賴注入酒甸。
頓悟
相信如果您認(rèn)真一步步看到這里魄健,對于下面的2個(gè)問題,您已經(jīng)有了自己的答案:
- 2.MyApplication實(shí)現(xiàn)的HasActivityInjector接口和實(shí)現(xiàn)的activityInjector()方法又是干嘛的
- 3.為什么這樣2行依賴注入代碼插勤,就能代替之前我們每個(gè)Activity都需要寫的模板代碼呢:
至此沽瘦,AndroidInject原理分析基本也到了尾聲
附錄
最后提供一下本文demo源碼連接和圖片資源,都已放到Github: