Does ViewModel survive Activity save and restore?
E

2

21

Instances of the new ViewModel class can survive configuration changes if used in the following fashion:

mViewModel = ViewModelProviders.of(this).get(MyViewModel.class);

However, in addition to configuration changes, there is also a save-restore scenario when the entire application's process is being killed.

Will fields' values inside ViewModel be preserved during save-restore scenario?


Edit: based on the answer to this question, I wrote this article: Android ViewModel Architecture Component is Dangerous

Endear answered 30/5, 2017 at 7:36 Comment(8)
There were already two attempts to answer this question, but the answers were deleted (probably because they were wrong). I guess this question is not that simpleEndear
Hmmm. That's why I commented.Katekatee
I doubt it though. When the process is killed, no objects survive. So it would have to be serialised and deserialised automatically which has it's own set of challenges. It also does not implement the Serialisable interface which might be an indication.Atomic
@Raghunandan, it wasn't about you. Just wanted to let people know that the question is far from trivialEndear
@RobCo, exactly my thoughts. They can't just store this object because it might contain a reference to e.g. Application. But I need a final confirmation before writing an angry blog post.Endear
@Endear well, I'd say dive into the source code then and try all thinkable scenarios and see how it behaves. Also, if you find a specific troublesome situation you should consider posting a feature request in the architecture component issue tracker. It is brand new after all, so not all edge cases might be covered.Atomic
@RobCo, I couldn't find the source code. If you happen to know where it is located, please answer this question: #44257400Endear
All the yarns lead to StateProviders class, from where SavedStateProvider can be accessed via static getter. But I couldn't find a component which will access those getters. If that class exists, it means that it has some purpose, which leads me to think that saving the state after process kill is something to be implemented in future releases.Chaldean
B
18

According to ViewModelProvider documentation (check get method), ViewModel is not preserved when app's process is killed:

The created ViewModel is associated with the given scope and will be retained as long as the scope is alive (e.g. if it is an activity, until it is finished or process is killed)

In addition check Ian Lake answer to similar question: https://medium.com/@ianhlake/you-are-correct-the-viewmodel-is-destroyed-if-your-process-is-killed-by-android-ef611fcd51e6

You are correct: the ViewModel is destroyed if your process is killed by Android. Just like before, you should use onSaveInstanceState() to store any data you must have to later recreate your Activity in the same state as before.

I also recommend reading Android ViewModel Architecture Component is Dangerous.

Batts answered 30/5, 2017 at 10:30 Comment(3)
Thank you. I'm waiting now to see if it is possible to get the source code of arch components. If it won't be possible, I will accept your answer as the most complete one.Endear
What if activity killed but not entire app? What if some foreground service survived - is ViewModel will survive too?Tolerable
Answer to my own question: no ViewModel will not survive even if app process not killed entirely.Tolerable
F
6

It seems Google offers a solution for this now

Saved State module for ViewModel

UI State is usually stored or referenced in ViewModel objects, not activities; so using onSaveInstanceState() requires some boilerplate that this module can handle for you.

When the module is set up, ViewModel objects receive a SavedStateHandle object via its constructor. This is a key-value map that will let you write and retrieve objects to and from the saved state. These values will persist after the process is killed by the system and remain available via the same object.


Setup

implementation 'androidx.lifecycle:lifecycle-viewmodel-savedstate:1.0.0-rc02' (November 7, 2019)


Usage

In order to set up a ViewModel to receive a SavedStateHandle you need to create them using a Factory that extends AbstractSavedStateVMFactory.

SavedStateViewModel vm = new ViewModelProvider(this, new SavedStateVMFactory(this))
        .get(SavedStateViewModel.class);

After that your ViewModel can have a constructor that receives a SavedStateHandle:


public class SavedStateViewModel extends ViewModel {
    private SavedStateHandle mState;

    public SavedStateViewModel(SavedStateHandle savedStateHandle) {
        mState = savedStateHandle;
    }
    ...
}

Storing and retrieving values

The SavedStateHandle class has the methods you expect for a key-value map:

  • get(String key)
  • contains(String key)
  • remove(String key)
  • set(String key, T value)
  • keys()
Freddafreddi answered 12/11, 2019 at 14:36 Comment(2)
A link to a solution is welcome, but please ensure your answer is useful without it: add context around the link so your fellow users will have some idea what it is and why it’s there, then quote the most relevant part of the page you're linking to in case the target page is unavailable. Answers that are little more than a link may be deleted.Clipper
Thank you for reminding me about this rule! I am aware that my answer with just a link is too little but at this time I felt unable to provide a more detailed answer that explains this well. I myself need to research more on this topic.Freddafreddi

© 2022 - 2024 — McMap. All rights reserved.