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

如何让子Fragment通过@Inject获取父Fragment创建的同一Service实例?

问题

在父Fragment中手动实例化了SomeService,通过childFragmentManager添加子Fragment后,希望子Fragment能通过@Inject注入父Fragment创建的同一个SomeService实例。

父Fragment代码:

@AndroidEntrypoint
class ParentFragment : Hilt_ParentFragment {
  var service: SomeService = SomeService(/* ... */)

  // ...

  childFragmentManager.commit {
    add(R.id.container, ChildFragment())
  }
}

子Fragment代码:

@AndroidEntrypoint
class ChildFragment : Hilt_ChildFragment {
  @Inject lateinit var service: SomeService
}

解决方案

要实现子Fragment注入父Fragment持有的同一个SomeService实例,需要借助Hilt的自定义组件作用域和模块提供实例的方式,步骤如下:

1. 定义Fragment级别的自定义作用域

创建自定义注解,标记该作用域为父Fragment及其子Fragment共享的范围:

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

2. 创建Hilt模块提供SomeService实例

编写模块,在父Fragment的组件中提供SomeService实例,并绑定到自定义作用域:

@Module
@InstallIn(FragmentComponent::class)
class ParentServiceModule {
    @Provides
    @ParentFragmentScope
    fun provideSomeService(): SomeService {
        return SomeService(/* ... */)
    }
}

若SomeService构造需要其他依赖,可直接在@Provides方法的参数中注入后传入。

3. 修改父Fragment代码,改用依赖注入

父Fragment不再手动创建SomeService,改为通过@Inject获取,并添加自定义作用域注解:

@AndroidEntrypoint
@ParentFragmentScope
class ParentFragment : Hilt_ParentFragment {
    @Inject lateinit var service: SomeService

    // ...

    childFragmentManager.commit {
        add(R.id.container, ChildFragment())
    }
}

4. 子Fragment保持原有代码即可

子Fragment的@Inject会自动从父Fragment所在的FragmentComponent中获取同一作用域的SomeService实例,无需额外修改:

@AndroidEntrypoint
class ChildFragment : Hilt_ChildFragment {
    @Inject lateinit var service: SomeService
}

原理说明

Hilt默认每个Fragment都有独立的FragmentComponent,但通过@ParentFragmentScope自定义作用域,可让父Fragment组件提供的实例在自身和所有子Fragment中共享——子Fragment的组件会继承父Fragment组件的作用域实例,从而保证注入的是同一个对象。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 00:10:19