本文假設讀者已經有一定Dagger2使用經驗
使用疑惑
之前工作中一直在使用dagger2進行開發,用起來確實很爽,但是我從我第一次使用我就一直有一個問題或者說疑問(本人才疏學淺腦子不夠使),通常情況下我們有如下清單
MyApplication,MyAppComponent,MyAppModule
ActActivity,ActComponent,ActModule
簡單解釋下,MyAppModule提供全局單例功能,比如打印日志,ActModule提供Activity級別的功能比如發起網絡請求(只是舉個栗子),現在我們希望在發起網絡請求的時候打印日志,那么解決方法也很簡單——SubComponent或者Component(dependencies=X.class)
于是我們首先在MyApplication中初始化MyAppcomponent(使用抽象類實現單例)
@Component(modules = MyAppModule.class)public abstract class MyAppComponent { ...... //使用SubComponent功能來完成component的組合 abstract ActComponent plus();}@Subcomponent(modules = ActModule.class)public interface ActComponent { void inject(ActActivity act);}public class MyApplication extends Application { @Override public void onCreate() { super.onCreate(); MyAppComponent.getInstance().inject(this); }}然后就是就在Activity中使用ActComponent來提供注入功能,代碼看上去就像如下...
MyAppComponent.getInstance() .plus() .inject(this);
為神馬我使用的明明是ActComponent,關MyAppComponent什么事?(我最開始學習使用dagger2的時候完全無法接受這種寫法),而且這似乎不太符合依賴注入的一個根本原則a class shouldn't know anything about how it is injected.
新用法
谷歌爸爸很明顯也注意到了這個問題,誰叫Dagger2在Android開發中也那么火呢,于是在Dagger2新版本中我們有了一個新東西dagger.android
Gradle引入方式
//dagger2 compile 'com.google.dagger:dagger:2.11' compile 'com.google.dagger:dagger-android:2.11' compile 'com.google.dagger:dagger-android-support:2.11' annotationProcessor 'com.google.dagger:dagger-compiler:2.11' annotationProcessor 'com.google.dagger:dagger-android-processor:2.11'
Demo地址在 https://github.com/hanliuxin5/Dagger2-demo
結合Demo和官方文檔粗略翻譯如下
1、在AppComponent中安裝AndroidInjectionModule
@Component(modules = {AndroidInjectionModule.class})public interface AppComponent { //....}2.編寫實現了AndroidInjector<YourActivity>的Lychee3Activity
@Subcomponent(modules = ...)public interface ActSubComponent extends AndroidInjector<Lychee3Activity> { @Subcomponent.Builder public abstract class Builder extends AndroidInjector.Builder<Lychee3Activity> { }}3.定義了ActSubComponent后,將其安裝在綁定了ActSubComponent.Builder的Module中,并且將該Module安裝在我們的AppComponent中
@Module(subcomponents = {ActSubComponent.class})public abstract class BuildersModule { @Binds @IntoMap @ActivityKey(Lychee3Activity.class) abstract AndroidInjector.Factory<? extends Activity> lychee3Activity(ActSubComponent.Builder builder); }@Component(modules = {AndroidInjectionModule.class, BuildersModule.class})public interface AppComponent { //....} 但是如果你的ActSubComponent若同我們在步驟2中定義的一樣,不管在類中還是在其Builder中沒有的方法和超類型,你可以用下面的代碼跳過2,3步驟
原文 Pro-tip: If your subcomponent and its builder have no other methods or supertypes than the ones mentioned in step #2, you can use @ContributesAndroidInjector to generate them for you
@ContributesAndroidInjector abstract Lychee2Activity lychee2Activity();
4.讓你的MyApplication實現HasActivityInjector,并且注入DispatchingAndroidInjector,
public class MyApplication extends Application implements HasActivityInjector { @Inject DispatchingAndroidInjector<Activity> dispatchingAndroidInjector; @Override public void onCreate() { super.onCreate(); DaggerAppComponent.builder().AppContent(this).build().inject(this);//最好結合demo來看,不然AppContent是啥你不知道 } @Override public AndroidInjector<Activity> activityInjector() { return dispatchingAndroidInjector; }}5.最后,在你Lychee3Activity和Lychee2Activity中的onCreate中,調super.onCreate()之前調用AndroidInjection.inject(this);
public class Lychee2Activity extends AppCompatActivity { public void onCreate(Bundle savedInstanceState) { AndroidInjection.inject(this); super.onCreate(savedInstanceState); }}至此,新東西的使用差不多就到這了,但是為什么我會有一種“天,怎么越來越復雜啦”的感覺呢...
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。
參考文章
https://google.github.io/dagger//android.html
https://android.jlelse.eu/android-and-dagger-2-10-androidinjector-5e9c523679a3
新聞熱點
疑難解答