Persisting Data

There are two general ways a user can leave an activity, and two different outcomes the user will expect:

  • The first is if the user completely closes the activity. A user can completely close the activity if they swipe an activity off of the recents screen or if a user navigates up or back out of an activity. The assumption in these cases is that the user has permanently navigated away from the activity, and if they ever re-open the activity, they will expect to start from a clean state. For our song app, if a user completely closes the song search activity and later re-opens the activity, the song search box will be cleared and so will the search results.
  • On the other hand, if a user rotates the phone or puts the activity in the background and then comes back to it, the user expects that the search results and song they searched for are there, exactly as before. There are a few ways the user could put the activity in the background. They could press the home button or navigate somewhere else in the app. Or they could receive a phone call or notification in the middle of looking at search results. In the end, though, the user expects when they come back to the activity, that the state is the same as they left it.

To implement this behavior in both situations, you will use local persistence, ViewModels and onSaveInstanceState() together. Each will store different data the activity uses:

  • Local persistence is used for storing all data you don’t want to lose if you open and close the activity.

Example: The collection of all song objects, which could include audio files and metadata

  • ViewModels are used for storing all the data needed to display the associated UI Controller.

Example: The results of the most recent search, the most recent search query

  • onSaveInstanceState is used for storing a small amount of data needed to easily reload activity state if the UI Controller is stopped and recreated by the system. Instead of storing complex objects here, persist the complex objects in local storage and store a unique ID for these objects in onSaveInstanceState().

Example: The most recent search query

When the activity is created — There are three different ways this could happen:

  • The activity is created for the first time: In this case, you’ll have no data in the onSaveInstanceState() bundle and an empty ViewModel. When creating the ViewModel, you’ll pass an empty query and the ViewModel will know that there’s no data to load yet. The activity will start in a clean empty state.
  • The activity is created after being stopped by the system: The activity will have the query saved in an onSaveInstanceState() bundle. The activity should pass the query to the ViewModel. The ViewModel will see that it has no search results cached and will delegate loading the search results, using the given search query.
  • The activity is created after a configuration change: The activity will have the query saved in an onSaveInstanceState() bundle AND the ViewModel will already have the search results cached. You pass the query from the onSaveInstanceState() bundle to the ViewModel, which will determine that it already has loaded the necessary data and that it does not need to re-query the database.

This is one sane way to handle saving and restoring activity state. Depending on your activity implementation, you might not need to use onSaveInstanceState() at all. For example, some activities don’t open in a clean state after the user closes them. Currently, when I close and re-open Chrome on Android, it takes me back to the exact webpage I was looking at before closing it. If your activity behaves this way, you can ditch onSaveInstanceState() and instead persist everything locally. In the song searching example, that would mean persisting the most recent query, for example, in Shared Preferences.

results matching ""

    No results matching ""