在屏幕旋转时重新创建 Android ViewModel [英] Android ViewModel recreated on screen rotation

查看:40
本文介绍了在屏幕旋转时重新创建 Android ViewModel的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现了架构组件 ViewModel 未保留的情况 - 简而言之,如下所示:

I found a case when architecture components ViewModel isn't retained - in short it goes as follows:

  1. Activity 启动并创建 ViewModel 实例
  2. 活动被置于后台
  3. 设备屏幕旋转了
  4. Activity 回到前台
  5. 调用ViewModel的onCleared方法并创建新对象
  1. Activity is started and ViewModel instance is created
  2. Activity is put to background
  3. Device screen is rotated
  4. Activity is put back to foreground
  5. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆