@Inject
有两种作用:
- 修饰构造函数时,告知 hilt 如何实例化该类
- 修饰成员属性时,告知 hilt 该属性需要注入实例
@Module 与 @InstallIn
定义 Hilt module。有些类无法通过 @Inject 注解的构造函数,Hilt 会从 @Module 中寻找这些类的实例化方法。一般 module 中会定义有 @Binds 和 @Provides 方法,分别对应不同情况
@InstallIn 指定该 module 处于哪个组件 component 中,不同的组件有不同的生命周期,一旦定义好所处的组件后,该 Module 提供的实例只能被限定在跟该组件对应的 scope 中,不可混用。如下会编译报错
@Module
@InstallIn(SingletonComponent::class)
abstract class M1Module {
@Binds
// 加了该注解后会编译报错,删除该注解即可编译通过
@ActivityScoped
abstract fun m1(impl: M1Impl): M1Itf
}
@Binds
注入接口实例。接口没有办法通过构造函数形式注入实现,hilt 通过自定义 Module,并在 Module 中使用 @Binds 注解抽象方法提供接口的实例。其作用有二
- 抽象方法返回值告知 hilt 该方法提供的是哪个接口的实例
- 抽象方法的参数告知 hilt 提供哪种实现
@Provides
注入无法通过构造函数注入方式构建的类的实例。此种情况包含以下可能:
- 该类属于第三方 sdk,无法个性 sdk 的代码,也就无法通过 @Inject 注解告知 hilt 如何实例化该类
- 该类实例化很复杂,比如需要通过 builder 模式才能实例化的类
跨模块通信
使用 hilt 可以实现跨模块通信
- 定义 base module,里面存放各 module 对外提供的功能 —— 封装成接口,将接口定义到 base module 中
- 各 module 依赖 base,并在自己 module 内部实现各自的接口
- 各 module 定义 hilt 模块,
通过 @Binds 或 @Provides 提供接口实例 - 使用者通过 Hilt 注入方式拿到各接口的实例
@Module
@InstallIn(SingletonComponent::class)
abstract class M2Module {
companion object{
@Provides
fun newStringBuilder(): StringBuilder {
return StringBuilder()
}
}
@Binds
@Singleton
abstract fun m2(impl: M2Impl): M2Itf
}
作用域 Scope
一个实例对象的存活时间有多种可能,比如全局单例、Activity 级单例等,Hilt 通过 Scope 管理各对象的生命周期,一般如下
- Singleton 全局单例
- FragmentScoped Fragment 级单例
- ActivityScoped Activity 级单例