MVVMArms系列 - 最新的 Dagger2.11(Dagg

作者: xiaobailong24 | 来源:发表于2017-09-18 11:03 被阅读1372次

    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,您可以通过以下平台找到我:

    相关文章

      网友评论

      • c6d1ead233c8:这和MVVM有关系吗?
        xiaobailong24:没关系,但是我是分解的MVVMArms里的Dagger.Android来说的。

      本文标题:MVVMArms系列 - 最新的 Dagger2.11(Dagg

      本文链接:https://www.haomeiwen.com/subject/brgvsxtx.html