hilt

49 阅读2分钟

@Inject

有两种作用:

  1. 修饰构造函数时,告知 hilt 如何实例化该类
  2. 修饰成员属性时,告知 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 注解抽象方法提供接口的实例。其作用有二

  1. 抽象方法返回值告知 hilt 该方法提供的是哪个接口的实例
  2. 抽象方法的参数告知 hilt 提供哪种实现

@Provides

注入无法通过构造函数注入方式构建的类的实例。此种情况包含以下可能:

  1. 该类属于第三方 sdk,无法个性 sdk 的代码,也就无法通过 @Inject 注解告知 hilt 如何实例化该类
  2. 该类实例化很复杂,比如需要通过 builder 模式才能实例化的类

跨模块通信

使用 hilt 可以实现跨模块通信

  1. 定义 base module,里面存放各 module 对外提供的功能 —— 封装成接口,将接口定义到 base module 中
  2. 各 module 依赖 base,并在自己 module 内部实现各自的接口
  3. 各 module 定义 hilt 模块,通过 @Binds 或 @Provides 提供接口实例
  4. 使用者通过 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 管理各对象的生命周期,一般如下

  1. Singleton 全局单例
  2. FragmentScoped Fragment 级单例
  3. ActivityScoped Activity 级单例