Page 1 of 2 Android apps can be stopped and restarted at any time. Managing an app's state is a big problem unless you master the bundle and more. Here's how to do it in Kotlin, in an extract from my published book Android Programming in Kotlin: Starting With An App.
Android Programming In Kotlin Starting with an App
Covers Android Studio 3 and Constraint Layout.
Is now available as a print book:
Buy from: Amazon
Contents
- Getting Started With Android Studio 3
- The Activity And The UI
Extract: Activity & UI
- Building The UI and a Calculator App
Extract: A First App
- Android Events
- Basic Controls
Extract Basic Controls Extract More Controls ***NEW!
- Layout Containers
Extract Layouts - LinearLayout
- The ConstraintLayout
Extract Bias & Chains
- Programming The UI
Extract Programming the UI Extract Layouts and Autonaming Components
- Menus & The Action Bar
- Menus, Context & Popup
- Resources
Extract Conditional Resources
- Beginning Bitmap Graphics
Extract Animation
- Staying Alive! Lifecycle & State
Extract State Managment
- Spinners
- Pickers
- ListView And Adapters
-
Android The Kotlin Way
If you are interested in creating custom template also see:
Custom Projects In Android Studio
Retaining State – the Bundle
When you change orientation your app is stopped and restarted. When this happens for example a TextView is reset to its default state when the app loads. This description of what is happening is perhaps what you might expect. However, this isn't the complete story.
The system does try to help you with the problem of having your app stopped in its tracks and restarted. It will automatically retain the state of UI elements that can be modified by the user, and it automatically restores them when the app starts.
So in principle you can initially ignore the problem of an app restart because the system restores your UI. This is the reason that some Android programmers assume that everything is "normal" and there is no need to study the lifecycle of an app. This is true at first, but later your app will evolve beyond what the system provides by default.
Automatically saving and restoring the UI's state is what the savedInstanceState parameter in the onCreate event handler is all about:
override fun onCreate(savedInstanceState: Bundle?) {
A Bundle is a set of key/value pairs which is used to save the values stored in UI elements when the app is stopped by the system. It stores id/value pairs and when the app is restarted the Bundle is used to initialize the values in the corresponding UI elements. Notice that if the user stops your app by removing it from the recent apps list then the savedInstanceState is destroyed, the app really does start over afresh, and the onCreate isn't passed a Bundle to restore the UI. In other words, savedInstanceState only restores the UI when the app has been stopped by the system.
It is also worth noticing that the restore will work to an alternative layout loaded because of a configuration change. For example, it will restore state to a landscape version of a layout as well as the original portrait version. All that matters is that the current layout has View objects with the correct ids.
At this point you are probably wondering why a modified TextView object isn't restored by the system when the device isrotated? The simple answer is that a TextView object isn't intended for user interaction – it is supposed to just be used to show static text labels and so the system doesn't save and restore it.
Saving Additional UI Data
The system will save and restore the state of the UI elements that the user can change, but it will not store any that your code changes. It also doesn't automatically save and restore any other data that the user or your code may have generated that isn't within the UI. In these cases you have to write some code that saves the values and restores them.
There are lots of ways of saving the state of an app as it is started and stopped by the system. One of the simplest is to use the Bundle object that the system uses.
The system fires the onSaveInstanceState event when it is about to add data to the Bundle and save it. If you want to save some additional data all you have to do is override the default event handler. For example, suppose you want to save and restore the data in the TextView in the Lifecycle Explorer (complete code in book). First you have to save the data:
override fun onSaveInstanceState(outState: Bundle?) {
super.onSaveInstanceState(outState)
outState?.putCharSequence("myText",textView.text)
}
Notice that we save the text content of the textView object as the value and use the key "myText". In most cases it would be better to create a string constant for the key. The key can be any identifier you care to use, but it has to be unique within the Bundle as it is used to retrieve the data you have stored in the Bundle.
Now to retrieve the data and place it into the TextView we need to change the onCreate event handler:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(toolbar)
textView.append("Create\n")
if (savedInstanceState != null){
textView.text= savedInstanceState.getCharSequence("myText")
}
This starts off in the usual way but now we check to see if savedInstanceState has any data. If it does we retrieve the stored text using the key "myText".
<ASIN:1871962544>
<ASIN:1871962536>
|