Dagger2在Android開發中的新用法.

本文假設讀者已經有必定Dagger2使用經驗html

使用疑惑

以前工做中一直在使用dagger2進行開發,用起來確實很爽,可是我從我第一次使用我就一直有一個問題或者說疑問(本人才疏學淺腦子不夠使),一般狀況下咱們有以下清單android

MyApplicationMyAppComponentMyAppModule
ActActivity,ActComponent,ActModulegit

簡單解釋下,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.學習

新用法

谷歌爸爸很明顯也注意到了這個問題,誰叫Dagger2Android開發中也那麼火呢,因而在Dagger2新版本中咱們有了一個新東西dagger.androidui

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

Talk is cheap, show me the code

結合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.BuilderModule中,而且將該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.最後,在你Lychee3ActivityLychee2Activity中的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...

相關文章
相關標籤/搜索