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

Dagger2/Android:setRetainInstance(true)的@FragmentScoped子组件随旋转重建

Dagger2:保留的Fragment每次注入都获取新依赖实例的问题分析

首先可以明确地说:这是Dagger2的预期行为,但你可以通过调整组件的作用域和依赖关系来解决这个问题。

为什么会出现这种情况?

当屏幕旋转时,Activity实例会被系统销毁并重建,绑定在Activity上的子组件(比如你的ActivityComponent)也会跟着一起重建。虽然你的Fragment通过setRetainInstance(true)保留了实例,但默认情况下,Fragment的注入依赖是依附于它所在的Activity子组件的。每次Activity重建后,新的ActivityComponent会创建全新的Fragment子组件,这就导致即使Fragment本身没被销毁,注入的依赖还是会变成新实例。

如何解决这个问题?

要让保留的Fragment的依赖实例也跟着Fragment一起存活,你需要让Fragment拥有独立于Activity的组件作用域:

1. 自定义Fragment专属的作用域

首先创建一个自定义的作用域注解,用来标记和Fragment生命周期绑定的依赖:

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

2. 让Fragment子组件直接依赖AppComponent

不要让Fragment子组件依附于ActivityComponent,而是直接将它挂在Singleton级别的AppComponent下,这样Fragment组件的生命周期就只和Fragment实例绑定:

// 定义Fragment子组件,使用自定义的FragmentScope
@FragmentScope
@Subcomponent(modules = [YourFragmentModule::class])
interface YourFragmentComponent {
    fun inject(fragment: YourRetainedFragment)

    @Subcomponent.Factory
    interface Factory {
        fun create(): YourFragmentComponent
    }
}

// 在AppComponent中声明Fragment子组件的工厂
@Singleton
@Component(modules = [/* 你的App级模块 */])
interface AppComponent {
    fun yourFragmentComponentFactory(): YourFragmentComponent.Factory
}

3. 只在Fragment第一次依附时注入

因为Fragment被保留了,所以不需要每次重建都调用注入,只在第一次onAttach时执行一次即可:

class YourRetainedFragment : Fragment() {
    private var isInjected = false

    override fun onAttach(context: Context) {
        super.onAttach(context)
        if (!isInjected) {
            val appComponent = (context.applicationContext as YourApp).appComponent
            appComponent.yourFragmentComponentFactory().create().inject(this)
            isInjected = true
        }
    }

    // 其他Fragment代码...
}

额外注意事项

  • 确保你的Fragment依赖都用@FragmentScope标注,这样Dagger会保证这些依赖实例和Fragment同生命周期,不会被重复创建。
  • 不要在onCreateView或其他每次重建都会触发的方法里调用注入,否则还是会重复创建依赖实例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:00:04