Android Adventures - Lifecycle And State
Written by Mike James   
Monday, 10 June 2013
Article Index
Android Adventures - Lifecycle And State
The Bundle
Advanced State Management

One of the things that you have to get used to when programming for a mobile platform is that your app can be shut down and restarted without much warning. You have to learn how to cope with this start-stop existence and that, for an Android app, its a tough life just trying to stay alive.

Android Adventures With Android Studio

Contents

  1. Getting Started With Android Studio
  2. The Activity And The UI
  3. Building The UI and a Calculator App
  4. Lifecycle and State
  5. Basic Controls And Events
  6. Spinners
  7. Pickers
  8. UI Graphics A Deep Dive
  9. ListView And Adapters
  10. Introducing Fragments
  11. Fragments and XML
  12. Fragment And Activity Working Together
  13. Managing Fragments
  14. Custom dialogs using DialogFragment
  15. Dialog Classes In DialogFragment
  16. A NumberPicker DialogFragment Project

 

Androidgears

Lifetime and State

Most programmers are used to the idea that their application will be started by the user, used and then terminated. If the application is restarted then it is usually up to the user to load whatever context they need - documents etc. Sometimes an application has to automatically retain state information from run to run. For example, a game might keep track of where a user had got to - which level and score - but this is about as complicated as things get. 

For an application running on a mobile device things are very different. The very nature of the device means that any application could be interrupted at any moment by an incoming phone call or the user making a phone call. To a certain extent this need to make app "interruptible" has been taken up by mobile phone operating systems as a more general principle. Android for example will stop your application running just because it needs the memory or wants to save battery life. It even terminates and restarts your application if a media reconfiguration is required. 

For example, as we discovered in the previous chapter if the user changes the orientation of the device then your app is terminated and restarted. This is not quite a restart from scratch because the system saves and restores some state information automatically but exactly how all this works is something we have to find out. 

The bottom line is that when you program under Android - and most other mobile operating systems - you have to care about the life cycle of your app and you have to take steps to ensure that its state is preserved so it can seem to the user that nothing at all has happened - even though you app has effectively been hit on the head and disposed of before being dragged back to continue from where it was. 

The Life Cycle Of An App

The different states that an Android app can be in and the transitions between them can seem complicated at first - that's because they are. If you are still thinking in terms of a desktop app that starts, runs and is terminated by the user this level of complexity can seem unnecessary - and perhaps it is.  However these are the rules that we have to play by.

The Activity class has a set of overridable event handlers for each of the states. These work in pairs - bracketing the three types of app state. 

At the outer most level there is

onCreate and onDestroy  - bracket the entire life of the app. This pair is called when the app is loaded into memory or unloaded from memory. These two bracket the entire lifetime of an activity. When it is first loaded the onCreate is triggered and when the app is disposed of onDestroy is triggered. You clearly have to use these two to setup and destroy and resources which are needed for the entire lifetime of the app - although in practice things can be more subtle.  The system can stop the app without calling the onDestroy and can restart the app triggering an onCreate event.

onStart and onStop - bracket any period that the app is visible. It could be that the app is behind say a modal dialog box. The app is visible but not interacting with the user. This pair of events can be triggered multiple times during the entire lifetime of the app. Simple apps can mostly ignore the onStart and onStop events because the app is still in memory and doesn't loose any resources or state. The main use of onStart and onStop is to give the app an opportunity to monitor any changes that might affect it while not interacting with the user.  To confuse the issue even more there is also on onRestart event which occurs before the onStart event but only if this isn't the first time the app has fired the onStart - that is this is a true restart. 

onResume and onPause - bracket the period that the app is in the foreground and interacting with the user. Again this pair of events can happen multiple times during the entire lifetime. The onResume event occurs when the app is in the foreground and doing its usual job. The onPause event occurs whent he user switches away to another app for example. 

The Simple Approach

At this point you have every right to be confused.

So many changes of status and what to do at each one? 

The main things to worry about is the complete restart of your app which triggers an onDestroy and an onCreate. This is the only one that destroys the current state of the app - the others are simply opportunities for your app to reduce the load on the system or to save some user data just in case. As the onDestroy is usually just an opportunity to clean up resources to avoid leaks this means that most simple apps really only have to hand the onCreate event.

However, is tempting to think that this starting and stopping is just like a desktop app being terminated and then the user decides to use it again when it is fine fof the app to start off as if it was being run for the first time. In the case of an Android app this isn't what the user expects at all. Your app can be terminated by the system without the user knowing anything about it. When the user tries to gain access to your app again they will generally expect it to carry on from where they left it.

It may be a complete restart as far as you are concerned but the user just switched to another app for a few minutes and expects to find yours as they left it.

Notice also that often these events occur in sequences. For example an app that has just received the onPause event is likely to go on to receive the onDestroy event because the system will remove it to free up memory say.  It is a mistake to try to think too much about sequences of events and ask which one should do any particular initialization or clean up.

Just think about the state that your app is moving into and place the necessary code into that event handler. 

Lifecycle Explorer

There is no better way to feel comfortable with the lifecycle and its events than to write a short demo program that shows you when they occur. 

Start a new Android blank activity application, accepting all defaults, and call it Lifecycle and then accept all the defaults to get started quickly. 

In the layout editor remove the "Hello World" string and place a TextView on the design surface. Next resize it so that it fills most of the area - it can be tricky to get it to snap to the size and remove its default text entry.

 

lifecyclescreen

 

The code is fairly easy the only trick is to remember to call each of the system provided event handler's that you have overridden. If you don't do this the app simply terminates when you run it. 

The OnCreate event handler still has to construct the UI but now we get a reference to the Java object representing the TextView:

private TextView textView;@Override
protected void onCreate(Bundle
                          savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 textView = (TextView)  
 findViewById(R.id.textView);
 textView.append("Create\n");
}

The rest of the program simply overrides each of the event handlers in turn, calls the original event handler and then adds a text message to textView:

@Override
protected void onStart() {
 super.onStart();
 textView.append("Start\n");
}

@Override
protected void onPause() {
 super.onPause();
 textView.append("Pause\n");
}

@Override
protected void onResume() {
 super.onResume();
 textView.append("Resume\n");
}

@Override
protected void onStop() {
 super.onStop();
 textView.append("Stop\n");
}

@Override
protected void onRestart() {
 super.onRestart();
 textView.append("Restart\n");
}

@Override
protected void onDestroy() {
 super.onDestroy();
 textView.append("Destroy\n");
}

A very simple and tedious sort of program - if you don't want to type it in or copy and paste it then you can find it in the CodeBin.



Last Updated ( Friday, 17 October 2014 )
 
 

   
Copyright © 2014 i-programmer.info. All Rights Reserved.
Joomla! is Free Software released under the GNU/GPL License.