Android ViewModel在其主机活动不在活动堆栈顶部且设备已轮换时重新创建

时间:2018-01-11 05:05:22

标签: android android-architecture-components android-mvvm

我在以下情况中:

我有一个包含ViewModel的OnboardActivity,我可以多次旋转这个OnboardActivity,并且ViewModel可以在没有问题的情况下保持配置更改。 但是,如果我使用startActivityForResult(...)在此(OnboardActivity)之上启动另一个Activity(FirebaseAuthActivity),然后在FirebaseAuthActivity中我旋转设备并按后退按钮。当OnboardActivity被带到堆栈顶部时,它会再次重新创建ViewModel实例。

这是ViewModel在架构组件中的正常行为吗?

有没有一种方法可以告诉OnboardActivity从堆栈中弹出时屏幕方向与保存的屏幕方向不同?

3 个答案:

答案 0 :(得分:2)

我已经回答了类似的问题here,到目前为止,这可能会帮助您修复自我。

这是来自android框架的错误。 Bug details

此修复程序在28.0.0-alpha3和AndroidX 1.0.0-alpha3中可用

但是,如果您自己现在不想更新到以上版本,则可以这样解决(我知道这是一个不好的解决方案,但我没有看到其他好的方法)

在您的活动中,重写onDestroy方法,然后在调用super.onDestroy之前将所有必填字段保存到局部变量中。现在调用super.onDestroy,然后再次初始化ViewModel,并将必填字段分配回ViewModel的新实例

关于isFinishing

以下代码在Kotlin中:

override fun onDestroy() {

  if (!isFinishing) { //isFinishing will be false in case of orientation change
      val oldViewModel = obtainViewModel()

      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)
}

答案 1 :(得分:1)

我在使用ViewModel时已经注意到同样的问题,并进行了一些研究,这里是场景:

  • 1)打开ActivityA -get ViewModel引用:TestViewModel @ e71fab8
  • 2)旋转设备 -get ViewModel引用:TestViewModel @ e71fab8
  • 3)打开ActivityB
  • 4)旋转设备
  • 5)按回(完成活动B)
  • 6)活动A从堆栈返回 -gets ViewModel,引用:TestViewModel @ 260072e

我已经使用两种ViewModel进行了测试,使用了工厂和默认创建方法:

  • ViewModelProviders.of(本)获得(TestViewModel :: class.java)
  • ViewModelProviders.of(此, 厂)获得(DashboardViewModel :: class.java)

这两个活动都扩展了AppCompatActivity类。

使用arch 1.1.1和1.1.0进行了测试。

-

答案 2 :(得分:0)

当打开相机或图库来挑选图像时,我也会发生这种情况。在相机/图库中旋转屏幕并返回,并重新创建视图模型。