屏幕旋转时重新创建了Android ViewModel [英] Android ViewModel recreated on screen rotation
问题描述
我发现没有保留架构组件ViewModel
的情况-简而言之如下:
I found a case when architecture components ViewModel
isn't retained - in short it goes as follows:
- 启动活动并创建
ViewModel
实例 - 活动被置于后台
- 设备屏幕旋转
- 活动放回前台
- 调用ViewModel的
onCleared
方法并创建新对象
- Activity is started and
ViewModel
instance is created - Activity is put to background
- Device screen is rotated
- Activity is put back to foreground
- ViewModel's
onCleared
method is called and new object is created
在这种情况下,我的ViewModel
实例被销毁是否是Android的正常行为?如果是这样,是否有建议的解决方案来保持其状态?
Is it normal behavior of Android that my ViewModel
instance is getting destroyed in this case? If so, is there any recommended solution of keeping its state?
我可以想到的一种方法是在调用onCleared
之后将其保存,但是,只要活动实际结束,它也将保持状态.另一种方法可能是使用onRestoreInstanceState
,但它会在每次屏幕旋转时触发(不仅是在后台运行应用程序).
One way I can think of is saving it once onCleared
is called, however, it would also persist the state whenever activity is actually finishing. Another way could be making use of onRestoreInstanceState
but it's fired on every screen rotation (not only if the app is in background).
有什么灵丹妙药来处理这种情况吗?
Any silver bullet to handle such case?
推荐答案
是的@tomwyr,这是来自Android框架的错误. 错误详细信息
Yes @tomwyr, this was a bug from an android framework. Bug details
此修复程序在28.0.0-alpha3和AndroidX 1.0.0-alpha3中可用
The fix is available in 28.0.0-alpha3 and AndroidX 1.0.0-alpha3
但是,如果您自己现在不想更新到上述版本,则可以这样解决(我知道这是一个不好的解决方案,但我没有看到其他好的方法)
But if you don't want to update to above versions now itself, Then you can solve like this (I know this is a bad solution but I didn't see any other good way)
在您的活动中,覆盖 onDestroy方法,并在调用super.onDestroy 之前,将所有必填字段保存到本地变量中.现在调用super.onDestroy,然后再次初始化ViewModel,并将必填字段分配回ViewModel的新实例
In your activity override onDestroy method and save all the required fields to local variables before calling super.onDestroy. Now call super.onDestroy then Initialize your ViewModel again and assign the required fields back to your new instance of ViewModel
关于 isFinishing
以下代码位于Kotlin :
override fun onDestroy() {
val oldViewModel = obtainViewModel()
if (!isFinishing) { //isFinishing will be false in case of orientation change
val requiredFieldValue = oldViewModel.getRequiredFieldValue()
super.onDestroy
val newViewModel = obtainViewModel()
if (newViewModel != oldViewModel) { //View Model has been destroyed
newViewModel.setRequiredFieldValue(requiredFieldValue)
}
} else {
super.onDestroy
}
}
private fun obtainViewModel(): SampleViewModel {
return ViewModelProviders.of(this).get(SampleViewModel::class.java)
}
这篇关于屏幕旋转时重新创建了Android ViewModel的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!