Dagger依賴注入詳解(三)

系列文章第一篇: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使用的一個總結,避免各種編譯不過的產生。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Dagger2 轉載請注明原作者,如果你覺得這篇文章對你有幫助或啟發,可以關注打賞。 前言本文翻譯自Google ...
    輕云時解被占用了閱讀 6,733評論 4 31
  • 部分內容參考自:[Android]使用Dagger 2依賴注入 - DI介紹(翻譯)[Android]使用Dagg...
    AItsuki閱讀 47,746評論 66 356
  • 2015年4月12日 我們的愛 / Farewell our love 回憶里想起模糊的小時候 In my mem...
    SS柴閱讀 172評論 0 1
  • 原理: Handler 、 Looper 、Message 這三個是Android異步消息處理線程相關的概念。異步...
    魔焰joy閱讀 225評論 0 1
  • 1組和8組的伙伴們,大家早上好! 我是向麗。向日葵的向,美麗的麗。一朵美麗的向麗葵 上一周我的踐行情況的話,還算是...
    Lily向麗閱讀 142評論 0 3