👏 ViewModel Saved State Review 👏

🤖::execute order process death::🤖

Costa Fotiadis
Feb 16, 2020 · 4 min read

The android framework has a curious case of killing any app that’s in the background for more than a few minutes.

Take this for example:

The RedditViewModel is responsible for fetching a post from Reddit while the calling activity/fragment is responsible for observing the redditPostData variable.

Once the post is fetched the activity’s observer is notified and we show it to the user.

award winning design™

This is all well and good until you put your app in the background and wait for a few minutes.

Or just kill the app yourself by clicking this little icon in the LogCat

Bringing the app to the foreground you might notice the post is all gone and we’re back to the initial CLICK ME state.

It seems that process-death murdered the redditPostData along with a bunch of other stuff.

In the olden days before android MVVM the UI state and other important variables would be kept with onSaveInstanceState() . Since viewmodels made an entrance, that has been sort of replaced in favor of using livedata.

The issue still exists though and is the sneaky cause of many bugs and crashes. ViewModel-SavedState is stable as of the end of January and is Google’s attempt at addressing the “just restart the app lol 🤣” crowd.

Add some dependencies first:

Source code for the project can be found here.

The RedditViewModel needs a SaveStateHandle to do the job of saving stuff on process death.

When working with Dagger one would normally use a ViewModelProvider.Factory that will be responsible for instantiating the ViewModel.

Since a SaveStateHandle is needed here, we’ll use AbstractSavedStateViewModelFactory instead.

RedditRepository is our own little class that can be instantiated in a dagger module or using the @inject annotation.

Providing the activity is not too hard either it seems. 🤔

I guess now is the right time to tie these together.

The activity should be all ready to get a RedditViewModel after we inject the factory in it like we normally do.

Injecting stuff in an activity is done with this classic that probably has a million different variations I’m missing.

While this isn’t really a Dagger tutorial (as if anyone can fully understand Dagger), you would need an application component and custom scopes to make this work. Check the repo for the whole thing.

Or get your DI set up the way you like it.

The RedditViewModel has changed slightly:

  • SavedStateHandle is just a map with all the stuff we might save in there.
  • On init we check if there’s anything saved in the SavedStateHandle. If we find something then process death has probably happened. Let’s update the redditPostData with that value and go back to the state we were.
  • Once the post is fetched we store that value in the SavedStateHandle and update the livedata like normal.

When running the app this guy will pop up sooner or later:

As with the activity’s onSaveInstanceState() , anything you would want to put in a bundle must implement Parcelable.

Let’s try that then.

Give the app another run and everything should work. Try initiating process death after fetching the reddit post with the red button found in LogCat too. The UI state should not be lost upon bringing the app in the foreground.

You might have noticed that the object stored in the bundle is a fairly simple one. Anything stored inside SavedStateHandle should be simple and lightweight.

Big lists / complex objects that are important for the functionality of an app regardless of system initiated process-death should preferably be stored in a database (like Room for example!).

Or you can just restart the app I guess. 🤡

Later.

The Startup

Get smarter at building your thing. Join The Startup’s +786K followers.

Sign up for Top 10 Stories

By The Startup

Get smarter at building your thing. Subscribe to receive The Startup's top 10 most read stories — delivered straight into your inbox, once a week. Take a look.

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information about our privacy practices.

Check your inbox
Medium sent you an email at to complete your subscription.

Costa Fotiadis

Written by

Android dude @JustEatUK

The Startup

Get smarter at building your thing. Follow to join The Startup’s +8 million monthly readers & +786K followers.

Costa Fotiadis

Written by

Android dude @JustEatUK

The Startup

Get smarter at building your thing. Follow to join The Startup’s +8 million monthly readers & +786K followers.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store