Configuration changes occur in runtime and are caused by various events such as: when keyboard visibility changes, when language changes, or when orientation changes. This in turn causes any visible Activity to be reconstructed once the change finishes. For state to be recovered, it needs to be explicitly tied to Android’s parcelling mechanism via Bundle.
Saving State, The Wrong Way
Upon encountering state loss caused by a configuration change, say on an orientation change, 2 poor solutions are:
1. Locking the orientation mode
1 2 3 |
|
This is an anti-solution and simply prevents the configuration change from occurring. This will not guard against the other 13 configuration changes as of API level 23.
Orientation should only be locked as a result of a UI/UX decision, and not for retaining state.
2. Handling configuration changes manually
1 2 3 |
|
Again, this is a band-aid and not a proper solution. What if new configuration changes are introduced? Also this might cause some unintended consequences. Say for example you want to declare a landscape/portrait-specific resource, that resource will not be loaded automatically anymore and you need to explicitly load and apply it in Activity#onConfigurationChanged() instead. Not knowing this consequence may be a pain to debug.
Quoting Roman Guy:
“…it is sometimes confusing for new Android developers who wonder why their activity is destroyed and recreated. Facing this “issue,” some developers choose to handle configuration changes themselves which is, in my opinion, a short-term solution that will complicate their life when other devices come out or when the application becomes more complex. The automatic resource handling is a very efficient and easy way to adapt your application’s user interface to various devices and devices configurations.”
Indeed, it is good practice to allow the system to do what it was designed to do as it allows your application to behave correctly on varying devices especially as your application gets more complex.
Manually handling configuration changes should only be done sparingly and as a result of some constraint (e.g. performance reasons).
Saving State, The Right Way
Luckily, framework Views will automatically be saved and recovered for you—assuming all your Views have unique IDs. In other instances you need to explicitly retain state.
Retaining State In An Activity
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
There are other lifecycle events where state can be restored such as in Activity#onCreate(). Retaining state in a Fragment can be done in a similar way via Fragment#onSaveInstanceState(). Here’s a good resource by CodePath for learning more about how this works.
Retaining State in A Custom View
Retaining state in a custom View is a bit more involved but nonetheless also fairly straightforward.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
|
TL;DR
- Don’t save your state the wrong way 😅 Save your state the right way 😁