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

DialogFragment中无法访问ViewModel的问题排查

问题原因

错误java.lang.IllegalStateException: Can't access ViewModels from detached fragment的核心原因是:你在CalenderFragment的构造阶段就初始化了ViewModel,此时Fragment还未关联到Activity(处于detached状态),无法访问ViewModelStore,导致抛出异常。

解决方案

有两种可靠的修改方式,推荐使用第一种:

方式一:使用Kotlin委托属性(推荐)

利用Jetpack提供的by viewModels()委托,它会自动在Fragment合适的生命周期(已attach到Activity)初始化ViewModel,无需手动管理时机:

class CalenderFragment : DialogFragment() { 

    // 使用by viewModels()委托自动初始化ViewModel
    private val viewModel: DViewModel by viewModels()

    private fun setMonthView() {
        val calenderHighlighter = CalenderHighlighter()
        val month = MonthSeperator(selectedDate!!)!!.toInt()
        val year = YearSeperator(selectedDate!!)!!.toInt()
        calenderHighlighter.positionsList(viewModel.retrivePositions(month, year))
    }

    // 其他必要的生命周期方法...
}

方式二:手动在生命周期方法中初始化

如果不使用委托,可以在Fragment已attach后的生命周期方法(比如onViewCreated或onAttach)中初始化ViewModel:

class CalenderFragment : DialogFragment() { 

    private lateinit var viewModel: DViewModel

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        // Fragment已关联视图,此时可安全获取ViewModel
        viewModel = ViewModelProvider(this).get(DViewModel::class.java)
    }

    private fun setMonthView() {
        val calenderHighlighter = CalenderHighlighter()
        val month = MonthSeperator(selectedDate!!)!!.toInt()
        val year = YearSeperator(selectedDate!!)!!.toInt()
        calenderHighlighter.positionsList(viewModel.retrivePositions(month, year))
    }
}
说明

两种方式都能确保ViewModel在Fragment处于attached状态时被初始化,避免访问ViewModelStore时的异常。by viewModels()是官方推荐的写法,代码更简洁且不易出错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 05:25:52