4

Dagger之十五、Hilt 中的单态部件

 2 years ago
source link: http://blog.chengyunfeng.com/?p=1127
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Dagger之十五、Hilt 中的单态部件

作者: rain 分类: Android Training 发布时间: 2021-10-30 13:20 6 0条评论

在 Hilt 中自动生成的 Dagger 部件是单态部件(Monolithic components),和单独使用 Dagger 中所定义的多态(polylithic)部件是有很大的区别的。

先来看看单态部件和多态部件是如何定义的,分别代表什么意思。

单态部件的意思是,在 Hilt 中只有一个 ActivityComponent 部件,一个安卓应用中的所有 Activity 类都是通过这一个 ActivityComponent 来注入的。对于 Fragment、Service、View 等其他安卓组件也是一样的,分别都只有一个该类型的子部件来注入所有的对象。 每个 Activity 都会通过 Application部件来获取到一个应用于该 ActivityActivityComponent 实例,两个不同的 Activity 所使用的是两个不同的 ActivityComponent 实例。 而多态部件就是我们在之前示例项目中为每个 Activity 单独创建一个子部件的情况,每个 Activity 都有自己对应的子部件,Activity 之间的子部件是无关联的,在前面使用 Dagger 安卓扩展库中的 @ContributesAndroidInjector 所生成的子部件也是多态的(为每个 Activity 单独生成一个子部件)。

可以看到在安卓组件所对应的子部件上,Hilt 中做了很大的变化,从多态部件变成了单态部件,本节课详细介绍为何 Hilt 中要使用单态部件这种模式。

单一的绑定空间(Single binding key space)

使用单态组件的最大好处之一就是同样的子部件里面绑定的对象合并到一个部件中了。比如您在一个 Fragment 中需要注入一个 Foo 类,对于多态部件,该 Fragment 可以从所属的 Activity 部件中获取这个 Foo 对象,如果 Fragment 应用在多个不同的 Activity 中,那么每个 Activity 子部件中所提供的 Foo 对象可能是不一样的,这样的话,有时候很有可能您很难定位这个 Foo 对象是从哪里生成的。 而在单态部件中,所有 Activity 子部件中的对象都合并到一个超级 ActivityComponent 上了,这样就很容易找到这个 Foo 对象的来源了。

虽然多态部件在每个 Activity 子部件上都可以很灵活的定义不同的依赖对象,但是通常而言随着应用代码量的增加,这种灵活性会导致代码变得越来越复杂。

如果对于一个仅仅在某一个 Activity 中使用的对象,在 Hilt 中推荐使用自定义限定符(qualifier) 注解 来实现该需求,或者使用 Service provider interface 插件来强制分离代码,关于 SPI 请参考这里

简化配置(Simplicity for configuration)

单一的绑定空间让配置更加简单。减少了一个 Dagger 模块可以被安装到不同部件中的次数,这样在测试的时候可以更容易的把一些对象替换为 mock对象。这样还无需担心模块中对象的扩散。比如在多态部件中,如果一个功能同时使用了 Fragment 范围的对象Activity 范围的对象,那么在使用的时候不但要把提供对象的模块安装到 Fragment 中,还要安装到所有使用该 FragmentActivity 中, 这样的话 Fragment 范围的对象就扩散到了所有使用该 FragmentActivity 中。 通常而言,这种配置的代码只是一些到处复制粘贴的模板代码并且很容易打破封装(breaks encapsulation)。

只需生成少量代码

使用单态部件还可以减少代码的生成量。当一个通用的模块被安装到多个子部件中的时候(例如一个 通用的 Activity 助手类),对于多态部件的情况,Hilt 要为每个子部件都生成一份安装该模块的代码。 对于一个简单的应用来说,可能这点代码量看起来也不算啥,但是当应用复杂以后,当应用中的 ActivityFragmentView 多了以后,这些代码量将会呈指数级增长,这样会导致生成大量的模板代码。

fastInit 和 应用的启动延迟

有些用户害怕使用 Dagger 导致应用启动变慢。如果您使用了 fastInit 编译选项(下一节课将介绍 Dagger 和 Hilt 编译选项),单态部件下对于应用启动的影响可以忽略不计。在 Hilt Gradle 插件中默认启用了 fastInit 选项,如果您在安卓应用中使用 Dagger,也应该启用该选项。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK