Instance State
So, with that in mind, let’s talk a bit about “instance state”.
Why Are We Passed a Bundle
in onCreate()
?
You may have noticed that all of our activities in the sample apps so far have an onCreate()
function that takes a Bundle
as a parameter. Each of the samples has done work in onCreate()
… and each of the samples has ignored this Bundle
.
This Bundle
is known as the “saved instance state”.
A Bundle
is a key-value store, using strings for keys and a limited set of data types for the values. Mostly, a Bundle
is designed to hold simple bits of data: Boolean
, Int
, Long
, String
, etc.
Normally, when our activity is created, the Bundle
parameter to onCreate()
is null
. That is why in Kotlin it is typed as Bundle?
instead of Bundle
.
If that Bundle
is not null
, it represents some state from some previous instance of our activity, where that previous instance either:
- Had been destroyed as part of a configuration change, or
- Had been nuked from orbit as part of Android terminating the app’s process, but the user happened to try returning to that app within 30 minutes of having left it
Our job is to use that Bundle
to help set up our user interface.
Nowadays, for the configuration-change scenario, we usually use a ViewModel
or something like that. However, a ViewModel
also gets nuked from orbit when the process is terminated, so that does not help us for the “return in 30 minutes” scenario.
When Do We Fill In the Instance State Bundle
?
Your activity can optionally override an onSaveInstanceState()
function. This will be passed a Bundle
, and you can fill data into that Bundle
.
Typically, you chain to the superclass, as Activity
will put things into the Bundle
related to your current on-screen widgets. In particular, Activity
will save some user-mutable data from those widgets, such as:
- The text that the user has typed into an
EditText
- The checked states of
CompoundButton
widgets likeSwitch
orCheckBox
- The position of a
SeekBar
When you chain to the superclass implementation of onSaveInstanceState()
, Activity
will save all that data for you. In addition, you can put your own data into the Bundle
.
In current versions of the Jetpack, we can adapt our ViewModel
classes to handle this work for us. We will see that later in the chapter.
When Do We Get the Instance State Bundle
?
Your activity will get a copy of that Bundle
back in two places:
-
onCreate()
, and onRestoreInstanceState()
onCreate()
is always called for a new activity instance. However, there may not be any instance state to restore, so its Bundle
parameter may be null
. onRestoreInstanceState()
is only called if there is instance state to restore, so its Bundle
will never be null
.
Your job is to look for this Bundle
and apply any data from it that you put into the Bundle
in onSaveInstanceState()
. Or, let your ViewModel
handle that.
What Are the Limits on the Bundle
?
As noted above, Bundle
does not support arbitrary data types. For your own custom classes, you can address this limitation via Parcelable
, as we will see in the next section. But you should not assume that you can put any sort of data into the Bundle
.
There is also a size limitation. The details are rather complicated, but the general rule of thumb is “keep your Bundle
well under 1MB”.
The instance state Bundle
is not designed to be a replacement for a local database or a server. Use it for in-flight data that you cannot easily load again and that should fit the data type and size limitations. Use your ViewModel
for data that you have loaded from disk or the network that you would prefer not to load again after a configuration change, and live with the fact that you will need to load that data again after your process has been terminated.
Prev Table of Contents Next
This book is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license.