Tuesday, March 13, 2012

ANDROID LIFECYCLE BASICS IN PRACTICE


Android applications must conform to the Android OS’s concepts of application
lifecycle.  Applications failing to code for application lifecycle can be less responsive, less
stable and less compatible across the range of Android devices than an app that even
handles simple lifecycle events.  This whitepaper is designed to provide guidelines and
tips for application developers with respect to handling common lifecycle events.


Android applications are based on several components, the most visible of which is the
Activity class (“visible” is literal, because it implements all UI and views in an Android
application).  Android specifies the lifecycle of each Activity in an application in detail,
known as the Android Activity Lifecycle.

Simple Android applications, especially 3D games that handle all user interfaces in the
3D engine tend to be single-Activity Android applications.  As a result, the concepts of
“application lifecycle” and “Activity lifecycle” can be considered as one and the same. 
We will do so for the purposes of this document. 

The Android lifecycle is exposed to applications via a set of callback member functions
in the application’s Java code.  At a top level, the basic sequence of Android lifecycle
callbacks follow a sort of “stack”, along with a set of additional callbacks that appear to
happen outside of this strictly hierarchical sequence.  We note the items that should
likely be handled in each.  This list is not exhaustive and covers mainly the common
ones.

The Lifecycle Hierarchy Events

The following events follow a basic hierarchy as indicated by indentation.  They are all 
override-able members of Activity.

onCreate: called to set up the Java class for the instance of the app

onStart: technically, called to initiate the “visible” lifespan of the app; at any time 
between onStart and onStop, the app may be visible.  We can either be 
onResume’d or onStop’ped from this state.  Note that there is also an event for 
onRestart, which is called before onStart if the application is transitioning from 
onStop to onStart instead of being started from scratch.

onResume: technically, the start of the “foreground” lifespan of the app, 
but this does not mean that the app is fully visible and should be 
rendering – more on that later

onPause: the app is losing its foregrounded state; this is normally an 
indication that something is fully covering the app.  On versions of 
Android before Honeycomb, once we returned from this callback, we 
could be killed at any time with no further app code called.  We can either 
be onResume’d or onStop’ped from this state

onStop: the end of the current visible lifespan of the app – we may transition to 
on(Re)Start to become visible again, or to onDestroy if we are shutting down 
entirely.  Once we return from this callback, we can be killed at any time with no 
further app code called on any version of Android.

onDestroy: called when the Java class is about to be destroyed.  Once this function is 
called, there is only one option for transition (other than being killed): onCreate.

The non-Hierarchy Events

Another set of important events are not hierarchical; we have seen them come in various 
levels of the previously described hierarchy events.  These events cover two categories: 
window focus and surface status.

Window Focus Callbacks

Window focus generally indicates whether an app’s window is the top-most, visible and 
interact-able window in the system.  There are two functions that relate window focus, 
and they seem to be redundant for apps with a single major view: 
Activity::onWindowFocusChanged and View::onWindowFocusChanged

 Each of these functions is passed a Boolean that indicates whether the callback is denoting 
focus gained or lost.  Starting from onCreate, focus is assumed not to be held, so
applications should be looking for an initial focus gained callback.  In general, focus gain 
seems to be indicated only with an app that is “resumed”, that is between onResume
and onPause callbacks. 

 However, as can be seen from callback sequences later in this 
document, an application may not receive a focus lost message before its onPause
callback is called.  In fact, in cases of quick shutdown for configuration changes, the 
system may go from resumed and focused all the way to onDestroy without ever 
indicating focus lost.  So onPause and onWindowFocusChanged must be used in 
tandem to determine the visible and interact-able state of the app.  It is this lack of focus 
lost callbacks at expected times which places the window focus events in the “nonhierarchical” category.

onPause versus onStop

In addition to the lifecycle state items previously mentioned, there is one other 
important difference between onPause and onStop callbacks.  The onPause callback Android Lifecycle Basics in Practice

Android Lifecycle for application developers: Guidelines and Tips  9
halts the visible UI thread, and thus any time spent in onPause will actively block the 
app’s UI interaction.  Thus, it is important to make onPause as responsive as possible 
while still saving absolutely key application state.

The onStop callback, on the other hand, is called once the app is no longer visible.  
Thus, while it is important to avoid ANRs from this callback, it is not pivotal to return 
immediately from onStop.  Spending a little more time in onStop will not cause 
application/device responsiveness issues.