使用 DispatchingAndroidInjector<> 和其他 dagger.android 类有哪些优点?

2023-12-26

我正在努力将 Dagger 2 设置到我的 android 项目中。这是我第一次使用这个框架,到目前为止一切都很顺利。但是我在项目中设置这个框架的方式上看到了不同的方法,我想知道哪一个更好,因为我比较了这两种方法,对我来说结果是一样的。

我遵循了这个指南:https://github.com/codepath/android_guides/wiki/Dependency-Injection-with-Dagger-2 https://github.com/codepath/android_guides/wiki/Dependency-Injection-with-Dagger-2

上网查了一下,都是采用这种方式。 它使用@Module和@Component来定义依赖项。

你的应用程序最终会像这样:

public class MyApp extends Application {

    private NetComponent mNetComponent;

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

        // Dagger%COMPONENT_NAME%
        mNetComponent = DaggerNetComponent.builder()
                // list of modules that are part of this component need to be created here too
                .appModule(new AppModule(this)) // This also corresponds to the name of your module: %component_name%Module
                .netModule(new NetModule("https://api.github.com"))
                .build();

        // If a Dagger 2 component does not have any constructor arguments for any of its modules,
        // then we can use .create() as a shortcut instead:
        //  mNetComponent = com.codepath.dagger.components.DaggerNetComponent.create();
    }

    public NetComponent getNetComponent() {
       return mNetComponent;
    }
}

但我找到了另一种方法(我没有测试过):https://google.github.io/dagger/android.html https://google.github.io/dagger/android.html它看起来完全不同,使用不同的类和注释。 它使用这样的东西:

@Subcomponent(modules = ...)
 public interface YourActivitySubcomponent extends AndroidInjector<YourActivity> {
   @Subcomponent.Builder
   public abstract class Builder extends AndroidInjector.Builder<YourActivity> {}
 }

@Module(subcomponents = YourActivitySubcomponent.class)
 abstract class YourActivityModule {
   @Binds
   @IntoMap
   @ActivityKey(YourActivity.class)
   abstract AndroidInjector.Factory<? extends Activity>
       bindYourActivityInjectorFactory(YourActivitySubcomponent.Builder builder);
 }

 @Component(modules = {..., YourActivityModule.class})
 interface YourApplicationComponent {}

public class YourApplication extends Application implements HasDispatchingActivityInjector {
   @Inject DispatchingAndroidInjector<Activity> dispatchingActivityInjector;

   @Override
   public void onCreate() {
     super.onCreate();
     DaggerYourApplicationComponent.create()
         .inject(this);
   }

   @Override
   public DispatchingAndroidInjector<Activity> activityInjector() {
     return dispatchingActivityInjector;
   }
 }

所以,我的问题是:

  1. 哪一个更好?

  2. 选择一种方法而不是另一种方法的原因是什么?


现在官方规定了 Android 版 Dagger 2 的设置方法Dagger 2 文档 https://google.github.io/dagger/android.html有很多优点,应该是首选。优点就是那里阐述的那些,即:

  1. 复制粘贴代码使得以后重构变得困难。随着越来越多的开发人员复制粘贴该块,很少有人知道它实际上做了什么。

  2. 更根本的是,它需要请求注入的类型(FrombulationActivity)来了解其注入器。即使这是通过接口而不是具体类型完成的,它也打破了依赖注入的核心原则:类不应该知道它是如何注入的。

让我们将这些原因应用到您的第一个示例中。

Reason 1

假设我们有一个 Activity 想要使用您的NetComponent。我们就这样称呼它吧NetActivity. The onCreate(Bundle savedInstanceState)那个方法NetActivity看起来像这样:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ((MyApp) getApplicationContext()).getNetComponent().inject(this);
}

该代码具有散落在燕麦片上的脚趾甲剪下的所有视觉吸引力(不是我的比喻),并且最终将复制粘贴到您使用的所有注射部位活动中NetComponent。如果您使用更复杂的组件,例如文档中的这个示例:

@Override
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  // DO THIS FIRST. Otherwise frombulator might be null!
  ((SomeApplicationBaseType) getContext().getApplicationContext())
     .getApplicationComponent()
     .newActivityComponentBuilder()
     .activity(this)
     .build()
     .inject(this);
 // ... now you can write the exciting code

}

更糟。它很容易退化为一段神奇的代码,必须在整个注入站点中复制并粘贴。如果发生变化,很容易忘记只更新一个网站,从而导致应用程序崩溃。

Reason 2

依赖项注入的一大优点是注入站点不需要知道或关心它们的注入器,就像依赖项不知道或关心它们的依赖项一样。回到我们的NetActivity, 我们有:

((MyApp) getApplicationContext()).getNetComponent().inject(this);

活动“知道”它的注入器(NetComponent),并且 Activity 现在与具体结合在一起MyApp和方法getNetComponent()来自同一个。如果这些类别中的任何一个发生变化,NetActivity也必须改变。

在 Dagger 版本 2.10 及更高版本中遵循 Activity 和 Fragment 内新注入方式的优点与这些缺点正好相反:

  1. 您最终会得到更少的复制粘贴代码
  2. 请求注入的类型不再需要知道或关心它们的注入器或其注入器的来源。

此外,正如指出的这个博客 https://medium.com/azimolabs/dagger-2-on-production-reducing-methods-count-5a13ff671e30#.p0au1nwnm,优先使用子组件而不是依赖组件可以减少应用程序的方法数量。

虽然使用子组件最初可能看起来更困难,但有一些明显的优点。然而,出于学习 Dagger 的目的,依赖组件最初可能更容易理解。如果第二个示例一开始太复杂,当您掌握了技巧后,您可以逐步采用首选方法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 DispatchingAndroidInjector<> 和其他 dagger.android 类有哪些优点? 的相关文章

随机推荐

  • r 闪亮滑块输入轮

    我的 R 闪亮滑块输入有问题 如您所见 圆形功能 不起作用在这幅图片中 https i stack imgur com v4nd6 png 我做错什么了吗 sliderInput Er Choose expected return in p
  • 在哪里检查 android 片段中的方向变化

    在我的应用程序中 我有一个FragmentActivity与多个Fragment除了一个特定的情况外 全部处于纵向模式Fragment 我在之间移动Fragment通过页脚View是在FragmentActivity 我有不同的布局 实际上
  • 如何测试我的 Django 电子邮件视图是否可以捕获 BadHeaderError?

    我有一个带有电子邮件表单的 Django 视图 它允许用户输入主题和消息 并将其作为电子邮件发送给站点管理员 我想编写一个单元测试来确保该视图可以捕获错误标头错误 https docs djangoproject com en 1 4 to
  • SQLiteAsyncConnection UpdateWithChildren 不可用

    我正在尝试使用 SQLite net 在我的 PCL 内实现 OneToMany 关系 我有异步扩展包 SQLiteNetExtensions Async 并且我的代码基于中找到的示例https bitbucket org twincode
  • 在 Google Analytics API 中使用和查询自定义维度

    我正在尝试查询我的 Analytics 通用 以接收按自定义维度排序的指标列表 7月 Google Analytics API 博客 http analytics blogspot com 2013 07 40 new data point
  • 循环图的数据结构和算法

    我需要定义Data Structure and Algorithm for Circular Data Graph对于网络客户端 在服务器上 数据将以 2 列 CSV 格式提供 例如发送方 接收方 最终输出将呈现在JSON格式并发送到网络请
  • 以编程方式设置约束

    我正在尝试如何使用 UIScrollView 经过一番折腾 我终于掌握了窍门 但现在我似乎遇到了另一个障碍 在这个简单的应用程序中 我有一个滚动视图 为了使其工作 我必须将视图的底部空间设置为滚动视图约束为 0 如上所述here https
  • Kotlin 有恒等函数吗?

    Scala 有一个泛型identityPredef 中的函数 def identity A x A A Kotlin 在标准库中有类似的工具吗 当然我可以简单地使用 it 相反 但我发现identity更容易阅读 并且实例化所有这些 lam
  • 根据用户角色和产品类别应用不同的税(Woocommerce)

    如果用户具有特定角色 但仅限于某些产品类别 我需要应用不同的税 示例 如果具有 Vip 角色的客户 A 购买 Bravo 或 Charlie 类别的商品 则适用的税费将为 4 而不是 22 这是我写的代码 另一部分是在谷歌上找到的 但我不明
  • 猫鼬更新 MongoDB 中的字段不起作用

    我有这个代码 var UserSchema new Schema Username type String index true Password String Email String Points type Number default
  • 重置 MySqli 指针?

    我在重置指针方面遇到了一些困难 我想这样做是因为我将在同一脚本中使用同一查询两次 据我所知 我可以在循环获取数组后重置指针来做到这一点 如果有更好的方法来做到这一点 我很想听听 无论如何 这就是我得到的 getEvent connectio
  • 设置默认样式键的方法之间的差异

    我正在创建一个自定义控件 源自Control 并想要为控件定义默认主题 以前我创建的所有自定义控件 我都使用过 static IntegerUpDown DefaultStyleKeyProperty OverrideMetadata ty
  • UIScrollView setContentSize 因未捕获的 NSRangeException 崩溃

    删除 UIScrollView 的某些内容后 调用 setContentSize 会使应用程序崩溃 int toolbarHeight self navigationController toolbar frame size height
  • Android Fragments API 无法正确显示背景 9patch 图像

    我正在将现有的 Android 应用程序以及片段 API 和兼容性库移植到 honeycomb 我使用相同的布局 但将其加载到片段中 背景是 9 块图像 但现在仅覆盖屏幕的左上四分之一 背景的其余部分是白色的 如果我将背景更改为十六进制颜色
  • 如何更新 phpunit?

    我已经尝试过了一切 包括https stackoverflow com a 8740349 251311 https stackoverflow com a 8740349 251311以及所有可能的通道升级和清除缓存命令 但仍然 sudo
  • 如何使用spark sql获取多个表

    我正在使用 pyspark 从 mysql 获取数据 该数据仅适用于一张表 我想从 mysql 数据库获取所有表 不想一次又一次的调用jdbc连接 请参阅下面的代码 是否可以简化我的代码 先感谢您 url jdbc mysql localh
  • 如何从父进程获取子进程

    是否可以在shell脚本中从父进程id获取子进程id 我有一个要使用 shell 脚本执行的文件 这会导致一个新进程process1 父进程 这process1已经分叉了另一个进程process2 子进程 使用脚本 我能够获得 pidpro
  • Laravel 雄辩的“WHERE NOT IN”

    我在编写查询时遇到问题laravel eloquent ORM 我的查询是 SELECT book name dt of pub pub lang no page book price FROM book mast WHERE book p
  • 使用 firebase 函数将数据推送到 Firestore

    您好 我是新的 firebase 函数 并尝试将数据推送到 firestore 通过下面的代码 我可以将消息推送到 firestore 并且它正在工作 exports addMessage functions https onRequest
  • 使用 DispatchingAndroidInjector<> 和其他 dagger.android 类有哪些优点?

    我正在努力将 Dagger 2 设置到我的 android 项目中 这是我第一次使用这个框架 到目前为止一切都很顺利 但是我在项目中设置这个框架的方式上看到了不同的方法 我想知道哪一个更好 因为我比较了这两种方法 对我来说结果是一样的 我遵