Handling configuration changes in Android can be a tricky subject. Configuration changes happen when you close an application, but also when you change the device’s orientation for example.
Historically it’s been common practice to use
onSaveInstanceState so your data survived configuration changes. The drawback to this is that using this doesn't allow for storing much data about the view.
Let’s look at an example app that we’ve built that generates a random number between 1 and 42 when the application starts.
Running that application should give us a result like this:
Great, we’ve been able to do this by writing the following code and calling that method from our activity:
Turning the device sideways should also give us that same result… right? Not really because that’s a configuration change, so any data we have on the screen gets fetched again. Were this an expensive API request, for example, we’d be making it again.
While this is just a simple application and the data here could very easily be stored inside
onSaveInstanceState, if we have a lot of data showing on the screen, this solution would be less than robust and limited to the amount of data we can save.
When an activity is created or recreated, it handles a few different tasks such as
- displaying the UI
- keeping track of user interaction
- handling the communication with the OS
And obviously loading any data from the network or database. Doing this time and time again can be expensive and if you have a lot of data, it means the user needs to get that data from somewhere every-single-time.
Using ViewModels we can store and manage all of our UI-related data in a lifecycle conscious way.
Here are the changes I had to make to the number generator project in order to benefit from that.
I first started by adding a dependency to the lifecycle extensions into my project.
I then modified my Datasource class to extend
ViewModel. This class generates a number between 1 and 42, but making it extend ViewModel as I did, changes its behaviour so it keeps state between configuration changes.
Lastly, I changed the MainActivity so instead of calling the
getMagicNumber() method directly, I now call it through the View Model Provider as follows:
With that, we have the ViewModel now processing the data that needs to be sent to the UI as well as performing any logic. As an added bonus it also survives any configuration changes.
Originally published at https://placona.co.uk on May 4, 2019.