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

Fragment中ViewModel旋转后无法保留实例问题排查

解决Fragment旋转后ViewModel重建的问题

问题根源

你当前的代码存在两个核心问题:

  1. MainActivity每次重建都会创建新Fragment实例:在onCreate方法中,无论savedInstanceState是否为空,都直接创建并替换新的VideoFragment。设备旋转导致Activity重建时,系统本可恢复原Fragment实例,但你强制创建新Fragment,导致原Fragment及其ViewModel被销毁。
  2. ViewModel绑定Fragment实例生命周期:当Fragment被重新创建时,对应的ViewModelStore会重置,调用ViewModelProvider(this)会生成新的ViewModel实例。

解决方案

方案1:让ViewModel绑定Fragment生命周期(旋转时保留)

修复MainActivity代码,仅在Activity首次创建时添加Fragment,配置变化时由系统自动恢复原Fragment:

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // 仅在首次创建时初始化Fragment,配置变化时跳过
        if (savedInstanceState == null) {
            supportFragmentManager.beginTransaction()
                .addToBackStack(null)
                .replace(R.id.main_container, VideoFragment())
                .commit()
        }
    }
}

Fragment中保持原有ViewModel获取方式即可:

class VideoFragment: Fragment() {
    lateinit var viewModel: VideoViewModel

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // 绑定Fragment生命周期,Fragment被系统恢复时复用原ViewModel
        viewModel = ViewModelProvider(this).get(VideoViewModel::class.java)
        return inflater.inflate(R.layout.fragment_video, container, false)
    }
}

设备旋转后,Fragment会被系统恢复,对应的ViewModel也会保留,不会重新实例化。

方案2:让ViewModel绑定Activity生命周期(跨Fragment共享)

如果业务需要ViewModel在Activity存活期间始终存在(比如多个Fragment共享数据),可使用requireActivity()作为ViewModelStoreOwner:

class VideoFragment: Fragment() {
    lateinit var viewModel: VideoViewModel

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // 绑定Activity生命周期,只要Activity不销毁,ViewModel就不会重建
        viewModel = ViewModelProvider(requireActivity()).get(VideoViewModel::class.java)
        return inflater.inflate(R.layout.fragment_video, container, false)
    }
}

这种方式无需修改Activity代码,但要注意:所有通过该方式获取ViewModel的Fragment会共享同一个实例,直到Activity销毁。

总结

  • 若ViewModel仅服务于当前Fragment,且希望随Fragment销毁而销毁:选择方案1。
  • 若需要跨Fragment共享数据,或希望ViewModel在Activity生命周期内持久存在:选择方案2。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 17:24:47