MVVMArms系列 - 最新的 Dagger2.11(Dagger.Android) 多 Module 實戰詳解

1 前言

距離首次接觸 Dagger2 已經有半年的時間了,從最初的一臉懵逼,到慢慢的熟練使用,這個過程真的感謝 MVPArms,這半年在 MVPArms 真的學到很多東西,由此演變出的 MVVMArms 可以說是這半年學習的結晶。其中在構建 MVVMArms 的過程中,采用了最新的 Dagger2.11,更好的支持了 Android 的依賴注入。好了,廢話就說這么多,下面來通過一個例子來對 Dagger.Android 有更進一步的認識。

下載源碼一起看會更好!下載源碼一起看會更好!下載源碼一起看會更好!

DaggerAndroid:https://github.com/xiaobailong24/DaggerAndroid

如果你還沒接觸過 Dagger2,可以看我之前轉載的一篇文章 - Dagger2 學習,里面概念講得很清晰。
目前大多數文章還是講解簡單使用 Dagger2,但是對于多 Module 下,怎么通過 Dagger 管理他們之間的依賴關系,還沒有這樣的文章,我會把在 MVVMArms 中探索出的一種 Dagger.Android 多 Module 管理方案分享給大家。

2 Gradle 配置

要在 Android 中使用 Dagger2 , 先添加 Gradle 配置,最新的版本可在 GitHub 找到。這里使用了 Android Studio 3.0 Beta6

  //dagger.android
  implementation 'com.google.dagger:dagger:2.11'
  annotationProcessor 'com.google.dagger:dagger-compiler:2.11'
  implementation 'com.google.dagger:dagger-android:2.11'
  implementation 'com.google.dagger:dagger-android-support:2.11'
  annotationProcessor 'com.google.dagger:dagger-android-processor:2.11'

3 入門篇

先來看一下幾個關鍵的概念:

  • @Component: Component 是一個注入器,就像注射器一樣,Component 會把目標類依賴的實例注入到目標類中,來初始化目標類中的依賴。
  • @Subcomponent: 從名字可以看出,這也是一個注入器,只不過被 @Subcomponent 注解的是被 @Component 注解的下一層級,這就像 Subcomponent 繼承于 Component 一樣。
  • @Module: 為一些三方類庫提供注入的對象,常配合 @Provides 使用。
  • AndroidInjectionModule: 主要提供 Dagger.Android 組件包,它應該被包含在注入 Application 的 Component 注入器的 modules 中。
  • AndroidInjection: Dagger.Android 注入的核心類,主要封裝了一些靜態方法用來為四大組件和 Fragment 進行注入。

Dagger.Android 可以有兩種注入方式,下面分別通過 Activity 和 Fragment 來看一下。

3.1 Activity 依賴注入(第一種注入方式)

3.1.1 AndroidInjectionModule

在整個 Application 的 Component 中添加 AndroidInjectionModule
AndroidInjectionModule 主要提供 Dagger.Android 組件包,它應該被包含在注入 Application 的 Component 注入器的 modules 中。
此例中為 AppComponent。

AppComponent

  @Singleton
  @Component(modules = AndroidInjectionModule.class)
  public interface AppComponent {
      void inject(MainApp mainApp);
  }

這樣就可以確保使用最新的 Dagger.Android

3.1.2 @Subcomponent

為 Activity 編寫 Subcomponent,該接口需要繼承 public interface AndroidInjector<T>;該接口內有一個被 @Subcomponent.Builder 注解的繼承于 AndroidInjector.Builder<T> 的抽象類,其中泛型 T 為要注入的目標 Activity。

MainActivitySubcomponent

  @ActivityScope
  @Subcomponent(modules = KobeModule.class)//DataModule
  public interface MainActivitySubcomponent extends AndroidInjector<MainActivity> {
      @Subcomponent.Builder
      abstract class Builder extends AndroidInjector.Builder<MainActivity> {
      }
  }

一些需要注入的數據類型可以包含在 @Subcomponent(modules = {}) 中。

KobeModule

@Module
  public class KobeModule {
      @ActivityScope
      @Provides
      public Person provideKobe() {
          return new Person("Kobe", 39);
      }
  }

Person

  public class Person {
      private String name;
      private int age;

      @Inject
      public Person(String name, int age) {
          this.name = name;
          this.age = age;
      }

      public String getName() {
          return name;
      }

      public int getAge() {
          return age;
      }
  }

3.1.3 @Module

接下來,編寫 Activity 的 Module,綁定上一步新建的 Subcomponent,這樣 MainActivitySubcomponent 就會為 MainActivity 注入 MainActivityModule 中提供的內容。
然后將其添加到全局 Component 中,即上文中的 AppComponent,這樣 AppComponent 就和 MainActivitySubcomponent 建立了聯系,這是一種繼承關系,即 Subcomponent 為 Component 的下一級。

MainActivityModule

  @Module(subcomponents = MainActivitySubcomponent.class)
  public abstract class MainActivityModule {
      /**
       * 第一種注入方式。需要 Subcomponent
       */
      @Binds
      @IntoMap
      @ActivityKey(MainActivity.class)
      abstract AndroidInjector.Factory<? extends Activity>
      bindActivityInjectorFactory(MainActivitySubcomponent.Builder builder);
  }

AppComponent 改寫為:

  @Singleton
  @Component(modules = {AndroidInjectionModule.class,
          MainActivityModule.class)
  public interface AppComponent {
      void inject(MainApp mainApp);
  }

3.1.4 HasActivityInjector

MainApp 實現 HasActivityInjector 接口,并注入 DispatchingAndroidInjector<Activity>
為 Activity 提供 AndroidInjector,這是 AndroidInjection.inject(Activity activity) 所需要的,具體見 3.1.6 的源碼解析。

MainApp

  public class MainApp extends Application implements HasActivityInjector {
      @Inject
      DispatchingAndroidInjector<Activity> mActivityInjector;

      private AppComponent mAppComponent;

      @Override
      public void onCreate() {
          super.onCreate();

          mAppComponent = DaggerAppComponent.builder()
                  .daggerComponent(getDaggerComponent())
                  .build();
          mAppComponent.inject(this);
      }

      public AppComponent getAppComponent() {
          return mAppComponent;
      }

      @Override
      public AndroidInjector<Activity> activityInjector() {
          return mActivityInjector;
      }
  }

3.1.5 AndroidInjection

最后,在目標 Activity 的 onCreate() 方法中進行注入,需要注意的是應該在 super.onCreate() 調用前注入。

MainActivity

  public class MainActivity extends AppCompatActivity {
    @Inject
    Person mKobe;//依賴注入

    public void onCreate(Bundle savedInstanceState) {
      AndroidInjection.inject(this);
      super.onCreate(savedInstanceState);
    }
  }

最后不要忘記在 AndroidManifest.xml 中指定 MainApp

3.1.6 源碼解析

AndroidInjection.inject()MainApp 獲得一個 DispatchingAndroidInjector<Activity> 對象,并將 MainActivity 傳入到 inject(Activity activity) 方法。 DispatchingAndroidInjector 為 MainActivity 類查找 AndroidInjector.Factory 的實現類,即 MainActivitySubcomponent.Builder;接著會創建一個 AndroidInjector,即 MainActivitySubcomponent,并將 MainActivity 傳入到 inject(Activity activity) 方法。

AndroidInjection#inject(Activity activity) 源碼如下:

  public static void inject(Activity activity) {
    checkNotNull(activity, "activity");
    Application application = activity.getApplication();
    //判斷 Application 是否實現了 HasActivityInjector 接口
    if (!(application instanceof HasActivityInjector)) {
      throw new RuntimeException(
          String.format(
              "%s does not implement %s",
              application.getClass().getCanonicalName(),
              HasActivityInjector.class.getCanonicalName()));
    }

    //從 Application 中獲取 AndroidInjector 對象,即 DispatchingAndroidInjector<Activity> mActivityInjector
    AndroidInjector<Activity> activityInjector =
        ((HasActivityInjector) application).activityInjector();
    checkNotNull(
        activityInjector,
        "%s.activityInjector() returned null",
        application.getClass().getCanonicalName());

    //最后注入到 MainActivity 中,此處是在 Dagger 編譯生成的 DaggerAppComponent.MainActivitySubcomponentImpl 類中實現的。
    activityInjector.inject(activity);
  }

3.2 Fragment 依賴注入(第二種注入方式)

Fragment 使用的是v4兼容包中的 android.support.v4.app.Fragment

3.2.1 @Subcomponent

由于在 Activity 依賴注入的第一步已經添加 AndroidInjectionModule,所以這里可以直接使用。這種方式其實是第一種方式的簡化,如果 MainFragmentSubcomponentMainFragmentSubcomponent.Builder 沒有其他的方法或超類型,如下,

MainFragmentSubcomponent

  @FragmentScope
  @Subcomponent
  public interface MainFragmentSubcomponent extends AndroidInjector<MainFragment> {
      @Subcomponent.Builder
      abstract class Builder extends AndroidInjector.Builder<MainFragment> {
      }
  }

這時可以省略 MainFragmentSubcomponent,也就是說,可以直接不用定義 MainFragmentSubcomponent

3.2.2 @Module

當 Subcomponent 和 它的 Builder 沒有其它方法或超類型時,可以不再需要 Subcomponent。
其實Subcomponent 的作用就是生成 AndroidInjector<T>,而 @ContributesAndroidInjector 注解也可以為我們做這個事情。

MainFragmentModule

  @Module
  public abstract class MainFragmentModule {
      /**
       * 第二種注入方式。當 Subcomponent 和 它的 Builder 沒有其它方法或超類型時,可以不再需要 Subcomponent
       */
      @FragmentScope
      @ContributesAndroidInjector(modules = JordonModule.class)//DataModule
      abstract MainFragment contributeMainFragment();
  }

一些需要注入的數據類型可以包含在 @ContributesAndroidInjector(modules = {}) 中。

MainFragmentModule 裝載到 AppComponent 中:

  @Singleton
  @Component(modules = {AndroidInjectionModule.class,
          MainActivityModule.class,
          MainFragmentModule.class})
  public interface AppComponent {
      void inject(MainApp mainApp);
  }

3.2.3 HasSupportFragmentInjector

讓要依賴注入的目標 Fragment(即 MainFragment) 的宿主 Activity(即 MainActivity) 實現 HasSupportFragmentInjector 接口。
為 Fragment 提供 AndroidInjector,這是 AndroidInjection.inject(Fragment fragment) 所需要的,具體見 3.2.5 的源碼解析。

MainActivity

  public class MainActivity extends AppCompatActivity implements HasSupportFragmentInjector {
    @Inject
    DispatchingAndroidInjector<Fragment> mFragmentInjector;
    //...

    public void onCreate(Bundle savedInstanceState) {
      AndroidInjection.inject(this);
      super.onCreate(savedInstanceState);
    }

    @Override
    public AndroidInjector<Fragment> supportFragmentInjector() {
        return this.mFragmentInjector;
    }
  }

如果使用 android.app.Fragment,Activity 應該實現 HasFragmentInjector 接口,并注入 DispatchingAndroidInjector<Fragment>
這一步也可以在 Application 實現 HasSupportFragmentInjector 接口,類似 3.1.4 所述。

3.2.4 AndroidInjection

最后,在目標 Fragment 的 onAttach() 方法中進行注入。

MainFragment

  public class MainFragment extends Fragment {
    @Inject
    Person mJordon;//依賴注入

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        AndroidSupportInjection.inject(this);
    }

    //...
  }

3.2.5 源碼解析

Fragment 注入的原理與 Activity 的類似,這里再強調一遍,其實第二種方式是第一種方式的簡化,使用 @ContributesAndroidInjector 注解來自動生成 Subcomponent

AndroidSupportInjection#inject(Fragment fragment) 源碼如下:

  public static void inject(Fragment fragment) {
    checkNotNull(fragment, "fragment");
    //獲取 HasSupportFragmentInjector
    HasSupportFragmentInjector hasSupportFragmentInjector = findHasFragmentInjector(fragment);
    Log.d(
        TAG,
        String.format(
            "An injector for %s was found in %s",
            fragment.getClass().getCanonicalName(),
            hasSupportFragmentInjector.getClass().getCanonicalName()));
    //從 Activity 中獲取 HasSupportFragmentInjector 對象,即 DispatchingAndroidInjector<Fragment> mFragmentInjector
    AndroidInjector<Fragment> fragmentInjector =
        hasSupportFragmentInjector.supportFragmentInjector();
    checkNotNull(
        fragmentInjector,
        "%s.supportFragmentInjector() returned null",
        hasSupportFragmentInjector.getClass().getCanonicalName());
    //最后注入到 MainFragment 中,此處是在 Dagger 編譯生成的 DaggerAppComponent.MainFragmentSubcomponentImpl 類中實現的。
    fragmentInjector.inject(fragment);
  }

AndroidSupportInjection#findHasFragmentInjector(Fragment fragment)

  private static HasSupportFragmentInjector findHasFragmentInjector(Fragment fragment) {
      Fragment parentFragment = fragment;
      while ((parentFragment = parentFragment.getParentFragment()) != null) {
        if (parentFragment instanceof HasSupportFragmentInjector) {
          return (HasSupportFragmentInjector) parentFragment;
        }
      }
      Activity activity = fragment.getActivity();
      if (activity instanceof HasSupportFragmentInjector) {
        return (HasSupportFragmentInjector) activity;
      }
      if (activity.getApplication() instanceof HasSupportFragmentInjector) {
        return (HasSupportFragmentInjector) activity.getApplication();
      }
      throw new IllegalArgumentException(
          String.format("No injector was found for %s", fragment.getClass().getCanonicalName()));
    }

由源碼可知,如果需要在 Fragment 中進行依賴注入,可以有兩種實現方式:一種是宿主 Activity 實現 HasSupportFragmentInjector,另一種是 Application 實現 HasSupportFragmentInjector。

3.3 其他組件

ServiceBroadcastReceiverContentProvider 的注入方式與此類似。
為了方便,Dagger.Android 為我們提供了一些封裝好的組件類,下面引用官方文檔的一段話,如果有需要,可以直接使用這些組件類。

Because DispatchingAndroidInjector looks up the appropriate AndroidInjector.Factory by the class at runtime, a base class can implement HasActivityInjector/HasFragmentInjector/etc as well as call AndroidInjection.inject(). All each subclass needs to do is bind a corresponding @Subcomponent. Dagger provides a few base types that do this, such as DaggerActivity and DaggerFragment, if you don’t have a complicated class hierarchy. Dagger also provides a DaggerApplication for the same purpose — all you need to do is to extend it and override the applicationInjector() method to return the component that should inject the Application.

The following types are also included:

Note: DaggerBroadcastReceiver should only be used when the BroadcastReceiver is registered in the AndroidManifest.xml. When the BroadcastReceiver is created in your own code, prefer constructor injection instead.

4 多 Module 實戰

上面只是簡單的介紹了Dagger.Android 的使用,下面重點來了,還是將通過一個例子,詳解怎么利用 Dagger 構建多 Module 依賴關系,從而實現組件化。
這里,將上述對 Activity 和 Fragment 的依賴注入分離到一個 Library Module 中,利用 Application.ActivityLifecycleCallbacksFragmentManager.FragmentLifecycleCallbacks 監聽,構建全局的依賴注入。

這里提前提一下本方案下,Dagger 的依賴關系:
DaggerComponent -> AppComponent -> MainActivitySubcomponent/MainFragmentSubcomponent
其中:DaggerComponent 為 library 的注入器,它的作用域是 @Singleton
AppComponent 為主 Module 的全局注入器,它的作用域是 @AppScope,并且 AppComponent 是依賴于 DaggerComponent,也就是說,DaggerComponent 頂級注入器,AppComponent 是主 Module 的注入器;
MainActivitySubcomponent/MainFragmentSubcomponent 是 Activity/Fragment 的注入器,作用域為 @ActivityScope/@FragmentScope,這里是 @Subcomponent,通過繼承的方式實現層級依賴,為 AppComponent 的下一級。

AppScope

  @Scope
  @Retention(RUNTIME)
  public @interface AppScope {
  }

4.1 Library Module

4.1.1 DaggerFragmentLifecycleCallbacks - 全局 Fragment 依賴注入

這里使用 FragmentLifecycleCallbacks 全局監聽 Fragment 的生命周期,對 Dagger.Android 進行統一注入管理。

DaggerFragmentLifecycleCallbacks

  public class DaggerFragmentLifecycleCallbacks extends FragmentManager.FragmentLifecycleCallbacks {

      @Inject
      public DaggerFragmentLifecycleCallbacks() {
      }

      @Override
      public void onFragmentAttached(FragmentManager fm, Fragment f, Context context) {
          super.onFragmentAttached(fm, f, context);
          Timber.i(f.toString() + " ---> onFragmentAttached");
          AndroidSupportInjection.inject(f);//Dagger.Android Inject for Fragment
      }

      @Override
      public void onFragmentActivityCreated(FragmentManager fm, Fragment f, Bundle savedInstanceState) {
          super.onFragmentActivityCreated(fm, f, savedInstanceState);
          Timber.i(f.toString() + " ---> onFragmentActivityCreated");
      }

      @Override
      public void onFragmentDetached(FragmentManager fm, Fragment f) {
          super.onFragmentDetached(fm, f);
          Timber.i(f.toString() + " ---> onFragmentDetached");
      }

  }

可以看到,DaggerFragmentLifecycleCallbacks 也是通過 Dagger 進行管理的,在 onFragmentAttached() 方法中進行 Fragment 的依賴注入;并且使用 Timber 打印了幾個關鍵生命周期回調Log。

4.1.2 DaggerActivityLifecycleCallbacks - 全局 Activity 依賴注入

這里使用 ActivityLifecycleCallbacks 全局監聽 Activity 的生命周期,對 Dagger.Android 進行統一注入管理。

DaggerActivityLifecycleCallbacks

  public class DaggerActivityLifecycleCallbacks implements Application.ActivityLifecycleCallbacks {
      @Inject
      DaggerFragmentLifecycleCallbacks mFragmentLifecycleCallbacks;

      @Inject
      public DaggerActivityLifecycleCallbacks() {
      }

      @Override
      public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
          Timber.w(activity + " ---> onActivityCreated");
          AndroidInjection.inject(activity);//Dagger.Android Inject for Activity
          if ((activity instanceof HasSupportFragmentInjector || activity.getApplication() instanceof HasSupportFragmentInjector)
                  && activity instanceof FragmentActivity) {
              ((FragmentActivity) activity).getSupportFragmentManager()
                      .registerFragmentLifecycleCallbacks(mFragmentLifecycleCallbacks, true);
          }
      }

      @Override
      public void onActivityStarted(Activity activity) {

      }

      @Override
      public void onActivityResumed(Activity activity) {

      }

      @Override
      public void onActivityPaused(Activity activity) {

      }

      @Override
      public void onActivityStopped(Activity activity) {

      }

      @Override
      public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

      }

      @Override
      public void onActivityDestroyed(Activity activity) {
          Timber.w(activity + " ---> onActivityDestroyed");
      }
  }

4.1.3 DaggerComponent - 頂級注入器

DaggerComponent

  @Singleton
  @Component(modules = {AndroidInjectionModule.class,
          DaggerModule.class})
  public interface DaggerComponent {
      Application application();

      void inject(DaggerDelegate daggerDelegate);
  }

其中 DaggerModule 主要提供一些全局依賴,這里只有一個 provideApplication() 方法,可以自行添加需要的東西。

DaggerModule

  @Module
  public class DaggerModule {
      private final Application mApplication;

      public DaggerModule(Application application) {
          mApplication = application;
      }

      @Singleton
      @Provides
      public Application provideApplication() {
          return this.mApplication;
      }
  }

4.1.4 DaggerDelegate - 開始注入

DaggerDelegate

  public class DaggerDelegate {
      @Inject
      DaggerActivityLifecycleCallbacks mActivityLifecycleCallbacks;

      private DaggerComponent mComponent;
      private final Application mApplication;

      public DaggerDelegate(Application application) {
          mApplication = application;
      }

      public void onCreate() {
          Timber.plant(new Timber.DebugTree());

          mComponent = DaggerDaggerComponent.builder()
                  .daggerModule(new DaggerModule(mApplication))
                  .build();
          mComponent.inject(this);

          mApplication.registerActivityLifecycleCallbacks(mActivityLifecycleCallbacks);
      }


      public DaggerComponent getComponent() {
          return mComponent;
      }
  }

這里的 DaggerDelegate 是一個代理類,為了克服 Application 繼承的問題,通過封裝一個代理類來對 library 的 Dagger 注入進行管理,然后在需要的 Module 里使用。

至此,Library Module 的依賴注入結構搭建完成。

4.2 App Module

由上一大節可知,Library Module 中是沒有 Application 的,它是一個 library,如果想使用它,需要在 主 Module 中進行依賴。再說一遍,DaggerComponent 是頂級注入器,AppComponent 主 Module 的全局注入器,它僅限定于 @AppScope
首先在 app/build.gradle 中添加上節中的 Library Module 依賴:

dependencies {
    //library
    implementation project(':library')

    //...
}

4.2.1 AppComponent - 主 Module 的全局注入器

AppComponent

  @AppScope
  @Component(dependencies = DaggerComponent.class,
          modules = {AppModule.class,
                  MainActivityModule.class,
                  MainFragmentModule.class})
  public interface AppComponent {
      void inject(MainApp mainApp);
  }

可以看到,dependencies = DaggerComponent.class,這就是上文所說的:AppComponent 是依賴于 DaggerComponent,也就是說,DaggerComponent 頂級注入器,AppComponent 是主 Module 的注入器
其中,AppModule 主要提供主 Module 的一些全局依賴,可自行擴展。

AppModule

  @Module
  public class AppModule {
      private Application mApplication;

      public AppModule(Application application) {
          mApplication = application;
      }
  }

4.2.2 MainApp - 真正注入的地方

MainApp

  public class MainApp extends Application implements HasActivityInjector {
      @Inject
      DispatchingAndroidInjector<Activity> mActivityInjector;

      private DaggerDelegate mDaggerDelegate;
      private AppComponent mAppComponent;

      @Override
      public void onCreate() {
          super.onCreate();

          //Library 的依賴注入(頂級)
          mDaggerDelegate = new DaggerDelegate(this);
          mDaggerDelegate.onCreate();

          //注入主 Module 中(該 Module 全局)
          mAppComponent = DaggerAppComponent.builder()
                  .daggerComponent(getDaggerComponent())
                  .build();
          mAppComponent.inject(this);

      }

      public DaggerComponent getDaggerComponent() {
          return mDaggerDelegate.getComponent();
      }

      public AppComponent getAppComponent() {
          return mAppComponent;
      }

      @Override
      public AndroidInjector<Activity> activityInjector() {
          return mActivityInjector;
      }
  }

MainApp 是真正進行依賴注入的地方,首先使用上一節 Library Module 中的 DaggerDelegate 進行頂級依賴注入,然后進行 主Module 的依賴注入。需要注意的是,MainApp 必須實現 HasActivityInjector 接口,才能進行 Dagger.Android 注入。

最后不要忘記在 AndroidManifest.xml 中指定 MainApp

4.2.3 MainActivityModule/MainFragmentModule

由第一節的例子可知:當 Subcomponent 和 它的 Builder 沒有其它方法或超類型時,可以不再需要手寫 Subcomponent,而是通過 @ContributesAndroidInjector 注解來自動生成。
所以,這里的 MainActivitySubcomponent/MainFragmentSubcomponent 可以省略;這樣,MainActivityModule/MainFragmentModule 如下:

MainActivityModule

  @Module
  public abstract class MainActivityModule {
    @ActivityScope
    @ContributesAndroidInjector(modules = KobeModule.class)//DataModule
    abstract MainActivity contributeMainActivity();
  }

MainFragmentModule

  @Module
  public abstract class MainFragmentModule {
      @FragmentScope
      @ContributesAndroidInjector(modules = JordonModule.class)//DataModule
      abstract MainFragment contributeMainFragment();
  }

KobeModule 和 JordonModule 依舊是第一大節中的,就不再重復貼代碼了。至此就可以在 Activity/Fragment 中進行依賴注入了。Dagger.Adnroid 注入是在 Library Module 中的 DaggerActivityLifecycleCallbacks/DaggerFragmentLifecycleCallbacks 完成的,這是一個全局監聽器,使用 DaggerDelegateMainApp 中進行注冊的。

4.2.4 總結

再來強調一下,本方案的 Dagger 層級依賴關系:

DaggerComponent -> AppComponent -> MainActivitySubcomponent/MainFragmentSubcomponent
其中:DaggerComponent 為 library 的注入器,它的作用域是 @Singleton
AppComponent 為主 Module 的全局注入器,它的作用域是 @AppScope,并且 AppComponent 是依賴于 DaggerComponent,也就是說,DaggerComponent 頂級注入器,AppComponent 是主 Module 的注入器;
MainActivitySubcomponent/MainFragmentSubcomponent 是 Activity/Fragment 的注入器,作用域為 @ActivityScope/@FragmentScope,這里是 @Subcomponent,通過繼承的方式實現層級依賴,為 AppComponent 的下一級。

5 總結

上面兩個例子,第一個介紹了 Dagger.Android 的簡單使用,這是 Dagger2.11 的新姿勢;這樣不需要每個 Activity/Fragment 中再重復手寫一串的依賴注入代碼;而是通過實現 HasActivityInjector/HasSupportFragmentInjector 接口,通過生命周期的監聽,使用 AndroidInjection.inject() 自動注入。
以上是 MVVMArms 框架的基本的 Dagger 層級依賴關系,更詳細的使用可以查看 MVVMArms
如果各位有任何疑問,歡迎交流。如果文中有不正之處,也請不吝賜教。
知識分享才會有快樂,后面我會繼續分解 MVVMArms 的關鍵模塊,如果各位對 MVVMArms 有任何問題或建議,歡迎一起交流。

6 Github

以上方案的源碼都可以在 Github 查看。

7 相關資源

  1. Dagger 2
  2. Dagger & Android
  3. Dagger2 學習

聯系

我是 xiaobailong24,您可以通過以下平臺找到我:

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,923評論 6 535
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,740評論 3 420
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,856評論 0 380
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,175評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,931評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,321評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,383評論 3 443
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,533評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,082評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,891評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,067評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,618評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,319評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,732評論 0 27
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,987評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,794評論 3 394
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,076評論 2 375

推薦閱讀更多精彩內容