As is true with iOS and Windows Phone development, you can’t get very far in Android development (with or without Xamarin) without understanding the Application Lifecycle in somewhat painful detail.
And, as explained in the previous blog post, some aspects of Android’s life cycle are, shall we say, unusual. The heart of an Android app, as you know by now, is an Activity. The rub is that activities can be suspended and resumed by the operating system, but not necessarily in the order they were created by the user. That is, while your third activity may originally have been called by your second Activity, when resumed by the OS it may be called all by itself with no prior context. This can complicate matters greatly.
In its essence, the Activity lifecycle is the collection of methods that the Operating System calls throughout the lifecycle of that Activity.
The states of an activity can be summed up in a fairly simple diagram,
Activities are Running if they are in the foreground. Activities in this state have the highest priority and are only killed by the Operating System in extreme and extremely unusual circumstances (such as trying to use more memory than exists on the device).
Activities are Paused under a number of circumstances:
The device goes to sleep
Another activity partially hides the activity
A transparent activity occludes the activity
Paused activities maintain their state an member information and remain attached to the Window manager. They have the second highest priority on the system.
An Activity is Backgrounded when they are completely obscured by another Activity. They attempt to maintain state, but are of the lowest priority and thus most likely to be killed by the OS to free up resources.
Until killed, an Activity can be resumed at any time without loss of state information. If the Activity is killed and then the user navigates back to it, it must be restarted and restored to its previous (saved) state. This, of course, is the responsibility of the developer and what makes programming Android interesting.
Configuration Changes and the Phoenix
The Operating System periodically tells the system to destroy itself and instantly re-create itself* in response to configuration changes such as changing the device’s rotation, displaying the keyboard or placing the device in the dock.To make sure that this reconfiguration is maximally fast, Android provides a special API to persist state during the reconfiguration.
There are a number of events associated with Life Cycle transitions. These are usually displayed using a flow chart, like the one found in the Xamarin documentation:
Your job is to override each of these event handlers.
|Note that the Application Life-cycle event handlers run on the UI thread and should be very short and very fast, or should delegate to a method running on the background thread.|
Let’s examine these one at a time:
Life-Cycle Event Handlers
The OnCreate event handler is almost always overridden to handle set up and initialization. The OnCreate handler takes a Bundle parameter which is a dictionary that you can use to store state information or to share objects between Activities. Note that the Bundle is null when the Activity is first started, so if it is not null you know that you are retarting and you must restore state from the previous instance.
The OnStart handler is called by OnCreate and calls OnResume. It is usually not overridden but can be if you need to do something only after the OnCreate is finished, but before an Activity becomes visible.
OnResume is called when the Activity is fully ready to start interacting with the user. This is a good method to override if you need to start listening to devices or start up animations. Also, if you have event handlers to attach, this is a good time to do so
OnPause may be the most critical of the Activities. It is called just before your Activity is put into the background. You typically will override this method to commit any unsaved changes, clean up objects that consume resources, free up resources that might otherwise become memory leaks and close any open dialogs or alerts.
From the OnPause event there are two possible paths: to the OnResume handler or, sadly, to the OnStop handler.
The OnStop handler is called when the Activity is no longer visible. Note, and this is critical: if there is not enough memory to put the Activity in the background, OnStop may be skipped and your Activity will go directly to OnDestroy. Do not count on OnStop being called. For this reason, it is not advised to take any important action in OnStop.
From OnStop again there are two possible paths: to OnResume or to OnDestroy
While in theory OnDestroy is the last event handler to be called before the Activity is killed, in fact if resources are low enough this event handler may also be skipped. It is best not to rely on OnDestroy being called.
Finally OnRestart is called if your activity has been stopped and prior to it being re-started. Because OnRestart is called both when the Activity is being created and also when it is being restarted, there are no guidelines for what should happen in this event handler. Typically, all set up work is done in OnStart. OnRestart is always followed by OnStart.
To sum this up, the critical event handlers are OnCreate and OnPause. The former is used for set up, the latter is used for tear-down. OnStop, OnDestroy and OnRestart are not terribly useful and are not typically overridden.
Saving And Restoring State
The key developer responsibility with regard to the Application Lifecycle, is to maintain instance state (the state of the Activity) when the Activity is being destroyed, and to restore that state when the Activity is re-started. Fortunately, Android makes this relatively easy to do by (a) providing the necessary methods and (b) providing a dedicated dictionary for handling serializable state data.
The OnSaveInstanceState method is invoked when the activity is being destroyed. This is your opportunity to save your data in key/value pairs to the Bundle. [Note that if you need to save more complex data that can be done as well, but is beyond the scope of this article and will be explained in a future blog post.]
There might be state that you only want to restore after all the objects in the Activity have been initialized.The OnRestoreInstanceState method is invoked after the OnCreate method finishes, and offers an opportunity for you to restore any state that wasn’t restored in OnCreate.
About the Author
Jesse Liberty is a Master Consultant for Falafel Software, an author and he creates courses for Pluralsight. Liberty hosts the popular Yet Another Podcast and his blog is required reading. He was a Senior Evangelist for Microsoft, a XAML Evangelist for Telerik, a Microsoft MVP, Distinguished Software Engineer at AT&T; Software Architect for PBS and Vice President of Information Technology at Citibank. Jesse can be followed on twitter at @JesseLiberty
Latest posts by Falafel Posts (see all)
- Matching Complex Query String Rewrite Rule in IIS - March 22, 2017
- Disable Content Filters in Sitefinity - March 8, 2017
- On Sitefinity Custom Widget Caching - February 22, 2017
- Dynamic Content Detail Widget Templates in Sitefinity - February 8, 2017
- Using Google Services in UWP C# Apps – Part 2 - February 7, 2017