本文假設讀者已經有必定Dagger2使用經驗html
以前工做中一直在使用dagger2
進行開發,用起來確實很爽,可是我從我第一次使用我就一直有一個問題或者說疑問(本人才疏學淺腦子不夠使),一般狀況下咱們有以下清單android
MyApplication
,MyAppComponent
,MyAppModule
ActActivity
,ActComponent
,ActModule
git
簡單解釋下,MyAppModule
提供全局單例功能,好比打印日誌,ActModule
提供Activity
級別的功能好比發起網絡請求(只是舉個栗子),如今咱們但願在發起網絡請求的時候打印日誌,那麼解決方法也很簡單——SubComponent
或者Component(dependencies=X.class)
github
因而咱們首先在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
來提供注入功能,代碼看上去就像以下...ide
MyAppComponent.getInstance() .plus() .inject(this);
爲神馬我使用的明明是ActComponent
,關MyAppComponent
什麼事?(我最開始學習使用dagger2
的時候徹底沒法接受這種寫法),並且這彷佛不太符合依賴注入的一個根本原則a class shouldn’t know anything about how it is injected.
學習
谷歌爸爸很明顯也注意到了這個問題,誰叫Dagger2
在Android
開發中也那麼火呢,因而在Dagger2
新版本中咱們有了一個新東西dagger.android
ui
Gradle引入方式this
//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...google
結合Demo和官方文檔粗略翻譯以下
在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); } }
至此,新東西的使用差很少就到這了,可是爲何我會有一種「天,怎麼愈來愈複雜啦」的感受呢...
第一次寫文章,有什麼不足的地方或者你以爲很不爽的東西歡迎交流指出。
參考文章
https://google.github.io/dagg...
https://android.jlelse.eu/and...