系列文章第一篇:http://www.lxweimin.com/p/33b739bd721a
系列文章第二篇:http://www.lxweimin.com/p/46fa16860f28
由于最近一直比較忙(lan),距離上篇已經兩個多月時間。我們先對上篇做個回顧:
1:Module - 提供依賴,相當于水源;
2:Component - 負責注入,相當于踩水車,導水管;
3:在Dagger自動生成的DaggerXXXComponent中,會持有其所依賴的Module,根據Module中@Provider注解生成相應的XXXModule_ProviderXXXFactory類。該類實現了Factory接口,Factory繼承自Provider接口XXXModule_ProviderXXXFactory重寫了get()方法,get()方法中會調用傳入的Module中具體的獲取實例的方法(該方法必須被@Provider注解)。
1.注入實現:
磨磨唧唧了這么久,終于要講到最重要的環節-實現注入了。實現注入的方式也很簡單,在你要注入的對象緊跟上一行加上@Inject注解。然后build一下項目,注入就完成了??吹竭@里你一定會心中暗罵:這么簡單那你之前磨磨唧唧說了那么多是干啥,浪費感情啊。莫急,我們系列既然是拆解分析dagger注入的原理,那么注入實現是重中之重,我們將會花大篇幅來介紹。
以Activity舉例:
下面是一個完整的注入實現過程:
public class OrderConfirmActivity extends BaseMvpActivity<OrderConfirmPresenter>{
}
public class BaseMvpActivity<T extends BasePresenter> extends BasicActivity{
@Inject
T mPresenter;
}
@ActivityScope
@Component(dependencies = AppComponent.class, modules = ActivityModule.class)
public interface ActivityComponent {
void inject(OrderConfirmActivity activity);
}
public final class DaggerActivityComponent implements ActivityComponent {
private Provider<OrderConfirmPresenter> orderConfirmPresenterProvider;
private MembersInjector<OrderConfirmActivity> orderConfirmActivityMembersInjector;
private MembersInjector<BaseMvpActivity<OrderConfirmPresenter>> baseMvpActivityMembersInjector;
private void initialize(final Builder builder) {
this.orderConfirmPresenterProvider = OrderConfirmPresenter_Factory.create(orderConfirmPresenterMembersInjector, retrofitHelperProvider);
this.baseMvpActivityMembersInjector = BaseMvpActivity_MembersInjector.create((MembersInjector) MembersInjectors.noOp(), orderConfirmPresenterProvider);
this.orderConfirmActivityMembersInjector = MembersInjectors.delegatingTo(baseMvpActivityMembersInjector);
}
@Override
public void inject(OrderConfirmActivity activity) {
orderConfirmActivityMembersInjector.injectMembers(activity);
}
}
逐步分析代碼:
一:我們有一個BaseMvpActivity,持有相應的Presenter,為了減少耦合,我們想將Presenter直接注入進來,而不是通過實例化,所以我們用@Inject注解我們想注入的Presenter(代碼中為OrderConfirmPresenter)。
二:我們將OrderConfimActivity注入到ActivityComponent中。
三:最重要的DaggerActivityComponent類中:
· 1:首先會生成Provider<OrderConfirmPresenter>對象
· 2:將生成的Provider<OrderConfirmPresenter>對象作為參數,創建基類Activity的MemberInjector對象MembersInjector<BaseMvpActivity<OrderConfirmPresenter>>
看一下其具體的過程:
public final class BaseMvpActivity_MembersInjector<T extends BasePresenter> implements MembersInjector<BaseMvpActivity<T>> {
private final MembersInjector<BasicActivity> supertypeInjector;
private final Provider<T> mPresenterProvider;
public BaseMvpActivity_MembersInjector(MembersInjector<BasicActivity> supertypeInjector, Provider<T> mPresenterProvider) {
assert supertypeInjector != null;
this.supertypeInjector = supertypeInjector;
assert mPresenterProvider != null;
this.mPresenterProvider = mPresenterProvider;
}
@Override
public void injectMembers(BaseMvpActivity<T> instance) {
if (instance == null) {
throw new NullPointerException("Cannot inject members into a null reference");
}
supertypeInjector.injectMembers(instance);
instance.mPresenter = mPresenterProvider.get();
}
public static <T extends BasePresenter> MembersInjector<BaseMvpActivity<T>> create(MembersInjector<BasicActivity> supertypeInjector, Provider<T> mPresenterProvider) {
return new BaseMvpActivity_MembersInjector<T>(supertypeInjector, mPresenterProvider);
}
}
可以看到關鍵代碼:instance.mPresenter = mPresenterProvider.get();這時候BaseMvpActivity中的mPresenter已經被賦值實例化了。所以剩下要做的就僅僅是調用injectMembers方法,完成賦值。
·3:生成MembersInjector<OrderConfirmActivity> orderConfirmActivityMembersInjector對象,只是簡單的調用了
MembersInjectors.delegatingTo方法將父類MembersInjector轉為子類MembersInjector:
public static <T> MembersInjector<T> delegatingTo(MembersInjector<? super T> delegate) {
return (MembersInjector<T>) delegate;
}
```
·4:調用injectMembers實現實例化Presenter:
```
@Override
public void inject(OrderConfirmActivity activity) {
orderConfirmActivityMembersInjector.injectMembers(activity);
}
```
根據第三部我們知道將MembersInjector<BaseMvpActivity<OrderConfirmPresenter>> 轉化為 MembersInjector<OrderConfirmActivity> orderConfirmActivityMembersInjector,我們調用子類的injectMembers方法,實際上是調用的父類的injectMembers方法,具體不再贅述。
通過以上分析,已經清晰明了的知道了通過@Inject注解,注入相應的對象到類中的過程。至此,Dagger注入的精髓我們都已經知道怎么實現了。下面會講一下其余的注解,但不會再對源碼進行分析,只是講解一下怎么使用。
2:@Qualifier:
Qualifier主要用于認證作用,對于同一個對象,但是不同實現方式,以確定使用哪個對象:
```
@Singleton
@Provides
@TestUrl
Retrofit provideTestRetrofit(Retrofit.Builder builder, OkHttpClient client) {
return createRetrofit(builder, client, TestApis.HOST);
}
@Singleton
@Provides
@ProductUrl
Retrofit provideVerRetrofit(Retrofit.Builder builder, OkHttpClient client) {
return createRetrofit(builder, client, ProductApis.HOST);
}
@Singleton
@Provides
ProductApis provideVerService(@ProductUrl Retrofit retrofit) {
return retrofit.create(ProductApis.class);
}
@Singleton
@Provides
TestApis provideTestService(@TestUrl Retrofit retrofit) {
return retrofit.create(TestApis.class);
}
```
簡單明了,限定了測試環境和生產環境使用的Retrofit對象。
3:@Scope
限定作用域,一般用于FragemtModule或ActivityModule中所提供對象的作用范圍。
至此,Dagger系列結束~~~~。算是對daager使用的一個總結,避免各種編譯不過的產生。