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

Android屏幕旋转后页面空白,Hilt配合SavedState初始化ViewModel报错如何解决

问题根因

  • 你同时使用了Hilt的@HiltViewModel注解和手动指定SavedStateViewModelFactory,两者逻辑冲突:@HiltViewModel会由Hilt自动完成ViewModel的依赖注入(包括注入SavedStateHandle、业务依赖如ImageListUseCase等),手动指定工厂后,系统会用你传入的工厂实例化ViewModel,而SavedStateViewModelFactory不知道如何注入你自定义的业务依赖,只会尝试调用无参构造函数,因此抛出找不到无参构造器的报错。
  • 多余的手动保存状态逻辑:SavedStateHandle本身已经和宿主Fragment的实例状态绑定,你不需要手动重写onSaveInstanceState触发保存。

修复方案

  1. 修改Fragment中ViewModel的初始化代码,删除手动传入的工厂:
// 修正前(错误写法)
private val imagePickerViewModel: ImagePickerViewModel by viewModels {
    SavedStateViewModelFactory(activity?.applicationContext as Application, this)
}

// 修正后(正确写法)
private val imagePickerViewModel: ImagePickerViewModel by viewModels()

你的Fragment已经加了@AndroidEntryPoint注解,Hilt会自动注入适配@HiltViewModel的ViewModel工厂,不需要手动配置。

  1. 删除Fragment中多余的onSaveInstanceState重写逻辑,不需要手动调用trigger()方法:
// 直接删除这段代码即可
override fun onSaveInstanceState(outState: Bundle) {
    imagePickerViewModel.trigger()
    super.onSaveInstanceState(outState)
}
  1. 优化ViewModel中的状态更新逻辑:savedStateHandle.getLiveData()返回的LiveData会和SavedStateHandle自动同步,你每次更新图片列表时,直接给savedStateHandle对应的key赋值即可,数据会自动持久化,页面旋转重建后自动恢复:
// 示例:当你获取到新的图片列表时调用该方法即可
fun updateImageList(newList: ArrayList<Image>) {
    savedStateHandle["key"] = Event(newList)
}

此时你的_observeImageListData会自动收到更新后的值,不需要额外手动同步。

验证逻辑

修改完成后运行项目,屏幕旋转后ViewModel不会重新走初始化请求逻辑,之前加载的图片列表会自动恢复,不会出现空白页面。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 18:57:02