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

Hilt自定义作用域对象添加Lazy Provider包装报错的解决方法

解决Hilt自定义作用域中Provider注入的MissingBinding错误

问题场景

在基于Hilt的自定义作用域项目中,尝试给CustomComponent.Builder添加Provider包装实现懒加载时,触发以下Dagger绑定错误:

[Dagger/MissingBinding] dagger.internal.Provider<com.example.testcustomscopes.TestService> cannot be provided without an @Provides-annotated method.
  public abstract static class SingletonC implements MyApplication_GeneratedInjector,

现有可运行的基础代码如下:

interface TestService {
    fun doSomething(): String
}

@CustomScope
class TestServiceImpl @Inject constructor() : TestService {
    override fun doSomething(): String {
        return "TestServiceImpl"
    }
}

@Module
@InstallIn(CustomComponent::class)
object AppModule {

    @CustomScope
    @Provides
    fun provideScopedClass(): TestService {
        return TestServiceImpl()
    }
}

@Scope
@Retention(AnnotationRetention.RUNTIME)
annotation class CustomScope

@CustomScope
@DefineComponent(parent = SingletonComponent::class)
interface CustomComponent {
    @DefineComponent.Builder
    interface Builder {
        fun build(): CustomComponent
    }
}

@InstallIn(CustomComponent::class)
@EntryPoint
interface CustomEntryPoint {
    fun getCustomDependency(): TestService
}

@Singleton
class CustomComponentManager @Inject constructor(
    private val customComponentBuilder: CustomComponent.Builder
) {
    private var customComponent: CustomComponent? = null

    fun createComponent() {
        customComponent = customComponentBuilder.build()
    }

    fun getComponent(): CustomComponent? {
        return customComponent
    }

    fun clearComponent() {
        customComponent = null
    }
}

@AndroidEntryPoint
class MainActivity : ComponentActivity() {

    @Inject
    lateinit var customComponentManager: CustomComponentManager

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        
        var customDependency: TestService? = null
        val customComponent = customComponentManager.getComponent()
        if (customComponent != null) {
            val entryPoint = EntryPoints.get(customComponent, CustomEntryPoint::class.java)
            customDependency = entryPoint.getCustomDependency()

            println(customDependency.doSomething())
        }
}

问题原因

Dagger Hilt不允许跨作用域直接请求子作用域对象的Provider实例:CustomComponentManager属于Singleton作用域,而TestService绑定在子作用域CustomComponent下,直接在父作用域中尝试获取子作用域对象的Provider会导致绑定缺失。同时,直接注入Provider<CustomComponent.Builder>不符合Hilt管理子组件创建的规范。


解决方案

1. 用ComponentFactory替代Provider<CustomComponent.Builder>

Hilt提供ComponentFactory来规范子组件的创建,这是获取子组件Builder的标准方式,替换CustomComponentManager的注入参数:

@Singleton
class CustomComponentManager @Inject constructor(
    private val customComponentFactory: ComponentFactory<CustomComponent.Builder>
) {
    private var customComponent: CustomComponent? = null

    fun createComponent() {
        customComponent = customComponentFactory.create().build()
    }

    fun getComponent(): CustomComponent? {
        return customComponent
    }

    fun clearComponent() {
        customComponent = null
    }
}

2. 按需为TestService添加懒加载(可选)

如果需要延迟TestService的实例化,修改CustomEntryPoint返回Provider<TestService>:

@InstallIn(CustomComponent::class)
@EntryPoint
interface CustomEntryPoint {
    fun getCustomDependency(): Provider<TestService>
}

使用时按需获取实例:

val customComponent = customComponentManager.getComponent()
if (customComponent != null) {
    val entryPoint = EntryPoints.get(customComponent, CustomEntryPoint::class.java)
    val testServiceProvider = entryPoint.getCustomDependency()
    // 需要时才创建实例
    val customDependency = testServiceProvider.get()
    println(customDependency.doSomething())
}

3. 移除冗余的Provider方法(优化)

TestServiceImpl已经有@Inject构造函数,AppModule中的provideScopedClass方法属于冗余代码,可以直接删除,Hilt会自动通过构造函数注入TestServiceImpl:

@Module
@InstallIn(CustomComponent::class)
object AppModule {
    // 移除provideScopedClass方法
}

内容的提问来源于stack exchange,提问作者Rowan Gontier

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 14:26:16