Android ViewModel recreated when its Host Activity was not in the top of Activity Stack and the device was rotated

匆匆过客 提交于 2019-12-21 12:54:39

问题


I am in the following scenario:

I have an OnboardActivity which contains a ViewModel, I can rotate this OnboardActivity many times and the ViewModel persist across configuration changes without issues.

However, if I launch another Activity(FirebaseAuthActivity) on top of this one (OnboardActivity) with startActivityForResult(...), and then in FirebaseAuthActivity I rotate the device and press the back button. When the OnboardActivity is brought to the top of the stack it recreates the ViewModel instance again.

Is this the normal behavior of ViewModel in architecture components?

Is there a way I can tell the OnboardActivity to not finish when it is pop from the stack with a screen orientation different than the one it was saved?


回答1:


I have answered to a similar question here, This might help you to fix your self as of now.

This was a bug from an android framework. Bug details

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)

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

about isFinishing

Below code is in 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)
}



回答2:


I Have notice the same issue when using ViewModel and made some research, here is the scenario:

  • 1) open ActivityA -gets ViewModel with reference: TestViewModel@e71fab8
  • 2) rotate device -gets ViewModel with reference: TestViewModel@e71fab8
  • 3) open ActivityB
  • 4) rotate device
  • 5) press back (finish Activity B)
  • 6) Activity A comes back from stack -gets ViewModel with reference: TestViewModel@260072e

I have tested with two kinds of ViewModel, with factory and default creation method:

  • ViewModelProviders.of(this).get(TestViewModel::class.java)
  • ViewModelProviders.of(this, factory).get(DashboardViewModel::class.java)

Both Activities extends AppCompatActivity class.

It was tested with arch version 1.1.1 and 1.1.0.

-




回答3:


This is also happening to me when opening the camera or the gallery to pick an image. Rotate the screen when in the camera / gallery and come back, and the view model gets recreated.



来源:https://stackoverflow.com/questions/48200085/android-viewmodel-recreated-when-its-host-activity-was-not-in-the-top-of-activit

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!