Hilt进阶--本文带你吃透Hilt自定义与跨壁垒

本文详细介绍了如何在Android中使用Hilt进行依赖注入,包括如何跨越IOC容器壁垒,自定义Scope和Component,以及解决独立library的依赖初始化问题。文章通过具体的代码示例和场景分析,阐述了EntryPoint、Component、Module的概念,以及如何通过自定义策略进行更灵活的管理。
摘要由CSDN通过智能技术生成

跨越 IOC容器的壁垒

使用依赖注入(DI)时,我们需要它对 实例依赖关系生命周期 进行管理,因此DI框架会构建一个容器,用于实现这些功能。这个容器我们惯称为IOC容器。

在容器中,会按照我们制定的规则:

  • 创建实例
  • 访问实例
  • 注入依赖
  • 管理生命周期

但容器外也有访问容器内部的需求,显然这里存在一道虚拟的 边界、壁垒。这种需求分为两类:

  • 依赖注入客观需要的入口
  • 系统中存在合理出现的、非DI框架管理的实例,但它不希望破坏其他实例对象的 生命周期作用域唯一性,即它的依赖希望交由DI框架管理

但请注意,IOC容器内部也存在着 边界、壁垒,这和它管理实例的机制有关,在Hilt(包括Dagger)中,最大颗粒度的内部壁垒是 Component

即便从外部突破IOC容器的壁垒,也只能进入某个特定的Component

使用EntryPoint跨越IOC容器壁垒

在Hilt中,我们可以很方便地

  • 使用接口定义 进入点(EntryPoint),并使用 @EntryPoint 注解使其生效;
  • @InstallIn 注解指明访问的Component;
  • 并利用 EntryPoints 完成访问,突破容器壁垒

下面的代码展示了如何定义:

UserComponent是自定义的Component,在下文中会详细展开

@EntryPoint
@InstallIn(UserComponent::class)
interface UserEntryPoint {
   
    fun provideUserVO(): UserVO
}

下面的代码展示了如何获取进入点,注意,您需要先获得对应的Component实例。

对于Hilt内建的Component,均有其获取方法,而自定义的Component,需从外界发起生命周期控制,同样会预留实例访问路径

fun manualGet(): UserEntryPoint {
   
    return EntryPoints.get(
        UserComponentManager.instance.generatedComponent(),
        UserEntryPoint::class.java
    )
}

当获取进入点后,即可使用预定义的API,访问容器内的对象实例。

自定义Scope、Component

部分业务场景中,Hilt内建的Scope和Component并不能完美支持,此时我们需要进行自定义。

为了下文能够更顺利的展开,我们再花一定的笔墨对 ScopeComponentModule 的含义进行澄清。

Scope、Component、Module的真实含义

前文提到两点:

  • DI框架需要 创建实例访问实例注入依赖管理生命周期
  • IOC容器内部也存在着 边界、壁垒,这和它管理实例的机制有关,在Hilt(包括Dagger)中,最大颗粒度的内部壁垒是 Component

不难理解:

  • 实例之间,也会存在依赖关系;
  • DI框架需要管理内部实例的生命周期;
  • 需要进行依赖注入的客户,本身也存在生命周期,它的依赖对象,应该结合实际需求被合理控制生命周期,避免生命周期泄漏

因此,出现了 范围、作用域Scope 的概念,它包含两个维度:实例的生命周期范围;实例之间的访问界限。

并且DI框架通过Component控制内部对象的生命周期。

举一个例子描述,以Activity为例,Activity需要进行依赖注入,并且我们不希望Activity自身需要的依赖出现生命周期泄漏,于是按照Activity的生命周期特点定义了:

  • ActivityRetainedScoped ActivityRetainedComponent,不受reCreate 影响
  • ActivityScopedActivityComponent,横竖屏切换等配置变化引起reCreate 开始新生命周期

并据此对 依赖对象实例 实施 生命周期访问范围 控制

可以记住以下三点结论:

  • Activity实例按照 预定Scope对应的生命周期范围 创建、管理Component,访问Component中的实例;
  • Component内的实例可以互相访问,实例的生命周期和Component一致;
  • Activity实例(需要依赖注入的客户)和 Component中的实例 可以访问 父Component中的实例,父Component的生命周期完全包含子Component的生命周期

内建的Scope、Component关系参考:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1TyMPMMu-1681042786597)(null)]
而Module指导DI框架 创建实例选用实例进行注入

值得注意的是,Hilt(以及Dagger)可以通过 @Inject 注解类构造函数指导 创建实例,此方式创建的实例的生命周期跟随宿主,与 通过Module方式 进行对比,存在生命周期管理粒度上的差异。

自定义

至此,已不难理解:因为有实际的生命周期范围管理需求,才会自定义。

为了方便行文以及编写演示代码,我们举一个常见的例

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值