You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Dagger Hilt中实现构造函数仅注入单个参数(其余为手动传入的普通参数)

如何在Dagger Hilt中实现构造函数仅注入单个参数(其余为手动传入的普通参数)

这个场景我之前开发时也碰到过,直接用@Inject构造函数确实没法实现“部分参数依赖注入、部分手动传入”的需求,不过Dagger Hilt专门提供了@AssistedInject和@AssistedFactory来解决这类问题,下面是具体的实现步骤:

方法一:使用AssistedInject(推荐方案)

这是Hilt官方推荐的处理“混合注入与手动参数”的方式,步骤清晰且易于维护:

  1. 修改CustomClass的构造函数注解
    把原来的@Inject换成@AssistedInject,同时给需要手动传入的参数添加@Assisted注解,明确告诉Hilt这个参数是外部手动传入的,不需要它提供依赖:
@AndroidEntryPoint 
class CustomClass @AssistedInject constructor (
    val repository: Repository,  // Hilt负责注入的参数
    @Assisted val name: String   // 手动传入的参数
) {}
  1. 创建Assisted Factory接口
    定义一个工厂接口,用@AssistedFactory注解标注,接口中声明创建CustomClass实例的方法,参数就是我们要手动传入的name:
@AssistedFactory
interface CustomClassFactory {
    fun create(name: String): CustomClass
}
  1. 通过工厂创建实例
    在需要初始化CustomClass的地方(比如Activity、Fragment,因为已经加了@AndroidEntryPoint),先注入这个工厂,再调用create方法传入name即可:
// 在你的Activity/Fragment中
@Inject lateinit var customClassFactory: CustomClassFactory

// 创建实例
val customClass = customClassFactory.create("name")

方法二:辅助构造函数(备选方案)

如果你暂时不想用AssistedInject,也可以通过拆分构造函数的方式实现,但这种方式相对繁琐一些:

  1. 调整CustomClass的构造函数
    主构造函数只保留需要Hilt注入的参数,然后添加一个辅助构造函数接收手动传入的name:
@AndroidEntryPoint 
class CustomClass @Inject constructor (val repository: Repository) {
    lateinit var name: String

    // 辅助构造函数
    constructor(repository: Repository, name: String) : this(repository) {
        this.name = name
    }
}
  1. 初始化实例
    在使用的地方,先通过Hilt注入Repository实例,再调用辅助构造函数创建CustomClass:
// 在你的Activity/Fragment中
@Inject lateinit var repository: Repository

// 创建实例
val customClass = CustomClass(repository, "name")

为什么原来的方式不行?

原来的@Inject构造函数要求所有参数都必须能被Hilt提供依赖,而name是我们要手动传入的自定义值,Hilt不知道该如何生成这个参数的实例,所以直接调用CustomClass("name")会报错。使用@AssistedInject则明确区分了注入参数和手动参数,让Hilt只负责它能处理的部分。

备注:内容来源于stack exchange,提问作者NullPointerException

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 09:39:29