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

Hilt中ActivityComponent作用域是否为Activity内所有Fragment提供同一实例?

问题

从谷歌官网的Hilt组件层级图可知,SingletonComponent会在整个应用中提供同一依赖实例。那么ActivityComponent是否也是如此?它会为所属Activity中的所有Fragment提供同一依赖实例吗?我运行了以下测试代码,得到了两个ID不同的AppNavigator实例!

测试代码

AppNavigator.kt

interface AppNavigator {
    fun navigate()
}

AppNavigatorImpl.kt

class AppNavigatorImpl @Inject constructor() : AppNavigator {
    val id = UUID.randomUUID().toString()
    override fun navigate() {
        Log.d("AppNavigator", "Navigating with instance $id")
        //navigation logic
    }
}
@InstallIn(ActivityComponent::class)
@Module
abstract class NavigationModule {
    @Binds
    abstract fun bindNavigator(impl: AppNavigatorImpl): AppNavigator
}

MainActivity.kt

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
    @Inject lateinit var navigator: AppNavigator

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        (navigator as AppNavigatorImpl).navigate()
    }
}

Fragment1.kt

@AndroidEntryPoint
class Fragment1 : Fragment() {
    @Inject lateinit var navigator: AppNavigator

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        (navigator as AppNavigatorImpl).navigate()
    }
}
问题原因与解决方案

问题核心在于依赖未标记对应组件的作用域注解。Hilt的组件(比如ActivityComponent)本身有生命周期,但如果依赖类没有添加与组件匹配的作用域注解,Hilt会在每次注入时创建新实例,即便模块已安装在该组件中。

要让ActivityComponent为所属Activity及其Fragment提供同一依赖实例,只需两步:

  • 给AppNavigatorImpl添加@ActivityScoped注解,标记该实例的生命周期与Activity绑定
  • 确保模块安装在ActivityComponent::class中(你已完成此步骤)

修改后的AppNavigatorImpl.kt代码:

import dagger.hilt.android.scopes.ActivityScoped

@ActivityScoped
class AppNavigatorImpl @Inject constructor() : AppNavigator {
    val id = UUID.randomUUID().toString()
    override fun navigate() {
        Log.d("AppNavigator", "Navigating with instance $id")
        //navigation logic
    }
}

修改后,MainActivity和Fragment1中注入的AppNavigator实例ID会完全一致——Hilt会在ActivityComponent的生命周期内复用这个实例。

补充说明:Hilt的组件层级中,FragmentComponent依赖于ActivityComponent,但只有当依赖被标记为@ActivityScoped时,Fragment才会从父组件(ActivityComponent)获取已存在的实例,而非创建新的无作用域实例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 03:10:03