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阅读 206,013评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,205评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,370评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,168评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,153评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,954评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,271评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,916评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,382评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,877评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,989评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,624评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,209评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,199评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,418评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,401评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,700评论 2 345

推荐阅读更多精彩内容