Android:使用activityViewModels时Activity销毁重建崩溃的解决求助
问题
使用KTX库的activityViewModels扩展实现Activity内Fragment共享ViewModel时,前台运行一切正常,但当应用退至后台导致Activity销毁,再次打开并处于第二个Fragment页面时发生崩溃,报错信息如下:
FATAL EXCEPTION: main java.lang.RuntimeException: Unable to resume activity {com.doddle.receivesort.us.inmar.stage/com.a..activity.xxActivity}: java.lang.RuntimeException: Cannot create an instance of class com.a.concession.workflow.sorting.features.SortParcelToContainerViewModel
相关代码实现:
第一个Fragment中创建ViewModel:
@Inject lateinit var viewModelFactory: SortToContainerViewModelFactory private val viewModel: SortToContainerViewModel by activityViewModels { viewModelFactory }
第二个Fragment中获取共享ViewModel:
private val sharedViewModel: SortToContainerViewModel by activityViewModels()
解决方案
1. 所有Fragment获取ViewModel时统一传入Factory
崩溃的核心原因是:Activity重建后,第二个Fragment调用activityViewModels()未指定Factory,而ViewModel的构造函数依赖外部注入,系统默认Factory无法创建实例。
修改第二个Fragment的代码,同样注入Factory并传入:
@Inject lateinit var viewModelFactory: SortToContainerViewModelFactory private val sharedViewModel: SortToContainerViewModel by activityViewModels { viewModelFactory }
确保所有需要共享ViewModel的Fragment都通过同一个Factory获取实例,保证Activity重建时能正确初始化ViewModel。
2. 在宿主Activity中提前初始化共享ViewModel
可以在Activity层级提前初始化ViewModel,确保Activity重建时Factory已就绪:
class XxxActivity : AppCompatActivity() { @Inject lateinit var viewModelFactory: SortToContainerViewModelFactory // 在Activity中提前初始化共享ViewModel private val sharedViewModel: SortToContainerViewModel by viewModels { viewModelFactory } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 确保依赖注入完成(如Dagger的inject调用) (application as MyApp).component.inject(this) } }
这种方式下,Fragment即使不指定Factory,也能复用Activity中已创建的ViewModel实例,但更推荐统一传入Factory的方式,避免依赖Activity的初始化顺序。
3. 检查ViewModelFactory的实现正确性
确认SortToContainerViewModelFactory能正确处理ViewModel的构造参数,比如实现create方法适配ViewModel的依赖:
class SortToContainerViewModelFactory @Inject constructor( private val requiredDependency: RequiredDependency ) : ViewModelProvider.Factory { override fun <T : ViewModel> create(modelClass: Class<T>): T { if (modelClass.isAssignableFrom(SortToContainerViewModel::class.java)) { @Suppress("UNCHECKED_CAST") return SortToContainerViewModel(requiredDependency) as T } throw IllegalArgumentException("Unknown ViewModel class") } }
同时确保依赖注入框架(如Dagger)已正确注入Factory自身的依赖,避免Factory初始化失败导致无法创建ViewModel。
内容的提问来源于stack exchange,提问作者srisindhu saride

