Best Practices for using onResume() in Android Apps

onResume() is a tricky part of an Android’s application life cycle that is called after onRestoreInstanceState(bundle), onRestart(), or onPause(). Its’ typical usage looks like this inside an Activity:

@Override
protected void onResume() {
	super.onResume();
	//do something
}

There are two things to be aware of when using onResume():

1)      The application may not be visible yet to the user

2)      Code that you want to access may not be fully initialized yet.

It seems very simple on the surface. When an application resumes it’s really no different than when you wake up in the morning. It may take some time to get going and there may be certain necessary rituals to be completed. For example, some people need a few cups of coffee (or tea), and applications are the same way. Of course, applications don’t drink coffee or tea (yet). But, anyway, it takes time and there may be certain rituals that need to be done for certain aspects of your application to spin back up. This is especially true when you have implemented your own threads.

It’s important to note: onResume() does not indicate that the application knows anything about the state of your application, and this is where you can get into trouble. This event is, for the most part, just an announcement by the operating system that it has resumed your Activity and that you can start accessing your app or hardware items such as the camera.  What makes this confusing is that some aspects of your Activity will come back to life without your help. Examples of this include user interface components. And, other aspects of your app will not automatically come back to life. An example of this is if you built any custom threads.

So, some key items to consider in your code are:

1)      If you are concerned about visibility then check onWindowFocusChanged(). You can do this using the pattern described below for #3 and #4.

2)      Did you pause any threads prior to the onResume() event? If you did, you’ll need to unpause them. If you don’t unpause them they won’t start back up again automatically.

3)      Do you have anything that takes additional time to re-initialize? An example of this might an RSS refresh request is kicked off, but the response payload hasn’t been received and processed yet and you want to synchronize that with other methods.

4)      If the device is under load when your application resumes, the methods you attempt to access and their responses, as well as any event handling, may be sluggish. Examples of a device under load include limited memory conditions, and/or high CPU usage, and/or high-bandwidth usage. If you don’t handle this properly the app will crash.

To work around items #3 and #4, there are several relatively easy ways to help prevent your app from crashing: Handlers and AsyncTasks. Use Handlers or AsyncTask for managing aspects of your application that don’t or can’t spring immediately back to life. If you aren’t familiar with Handlers or AsyncTask, they give you an easy way to off-load time-consuming or intensive tasks from the main user interface thread, and they also provide easy methods for re-synching messages, methods or objects back into the main thread. The concept behind this is the end user can continue working with a compliant user interface that still accepts input, while these special methods work on their tasks in the background, and then return control back to the main thread when the tasks are done.

There are plenty of posts that explain Handlers and AsyncTasks and show how to fully implement them, so I’m not going to cover that. I will, however, show you one example to demonstrate what I’d consider a best practice to cover you on items #3 and #4. In this example, and in the context of the application being resumed, it must now wait until the RSS feed has been retrieved before running an analysis on the feed. Both the RSS HTTP request/response and the analysis can be time consuming, and the analysis could still be running in the background while another RSS feed request is taking place. By using background threads, we can better manage this scenario and reduce the chance of an application crash.

public boolean getRSSPayloadReady(){
	boolean rssRecieved;
	//determine if RSS has been recieved and processed.
	....
	return rssRecieved;
}

@Override
protected void onResume() {
	super.onResume();
	rssQueue.unpause(); //threaded method for retrieving RSS
	delayedStart(15000);
}

/**
* Use with onResume().
* Check for RSS update in the background using a specified second delay.
* @param delay how long to wait in milliseconds
*/
public void delayedStart(final int delay){
	final Handler handler = new Handler();

	Runnable rssTask = new Runnable() {

		@Override
		public void run() {

			try{
				handler.postDelayed(new Runnable() {

					@Override
					public void run() {

						try{
							boolean test = getRSSPayloadReady(); //Has RSS refresh completed?

							if(test == true){
								//this algorythm runs as AsynTask
								runParsingAlgorythm(); //won't work if RSS payload = null
							}
							else{
								sendToastMessageRSSFailed(); //Let user know there was a problem.
							}
						}
						catch(Exception exc){
							Log.d("Test","delayedStart(): " + exc.getMessage());
						}
					}
				}, delay);
			}
			catch(Exception exc){
				Log.d("Test","delayedStart(): " + exc.getMessage());
			}
		}
	};

	Thread rssThread = new Thread(rssTask);
	rssThread.start();
}

Reference:

Android Activity and Application Life Cycle

Event-based architectures for Adobe Flex

I had a number of interesting conversations in the last few weeks with developers who were experiencing life-cycle issues in their Flex applications, especially when their apps were run on slower machines…or even smart phones. They eventually had figured out that there were certain places in their apps where they had hardcoded properties into Classes. And, when those properties weren’t initialized in the right order…the code block which requested those properties failed with null exception errors.

Since Flex doesn’t have threads we are dependant on the linear execution of the code, which just so happens to include MXML, ActionScript and occasionally JavaScript. That means, for the most part, that your code is executed one line at a time, in the order in which it was written. 

To give you an example of how this can go wrong: if you are expecting an MXML custom component to be initialized with all its properties populated, you’ll get null value exceptions if this hasn’t occurred when you try and display that custom component. And, when you look at in the debugger you’ll be astonished to see all your properties are null or uninitialized in some way.

The bottom-line is if you don’t understand the life-cycle of your app you could end up severely beating your head against a wall for hours (or days) trying to figure out what’s going wrong. I don’t know why, but Adobe doesn’t talk much about life-cycle. To me, it’s mission critical to understand it. If you want to build anything more than very simple applications, I gaurantee you’ll eventually have to deal with it. Now fortunately there are some excellent articles out there. I highly recommend this excellent PDF by DevelopmentArc. Read it!

I also recommend making your architectures more loosely coupled, and event-based, rather than expecting immediate results. It may seem counter-intuitive at first. What it means is you can tie your code together based on something that happens in the future. And, your app will wait until that event occurs, then it will proceed as directed and not a moment sooner. 

So what am I talking about? For example, if you make a request to a REST Web Service, you can assign an event dispatcher to fire off when the response payload has been received and an event listener somewhere else in your app will wait for that event to occur. Sometimes servers take a while to respond, or maybe the internet was slow, or maybe the smartphone temporarily had a bad cell connection. When that happens, it will delay when your app recieves the payload. Or if you don’t receive a payload back after a certain period of time, you can throw an error event. All these types of scenarios can be gracefully handled with built-in ActionScript events as well as custom events that you build.

What’s the alternative? If your application immediately asks for a result and the response payload got delayed, guess what? You’re app will fail or throw an error.

I also want to throw one more bone of caution your way. Events themselves are subject to what’s called propogation. You may not want to, but you really do need to read as much about propogation as you can! Once you have a basic understanding of both application life-cycle and propogation you will be able to build much more robust applications. And in the long run that translates to more time you can dedicate to watching basketball, football, or whatever else you want to do with your new found “free” time.

So, my suggestion is make judicious use of custom events. Here’s a short article from Adobe on how to do it.

References:

DevelopmentArc – Understanding the Adobe Flex® 3 Component and Framework Lifecycle

Adobe – Dispatching Custom Events

Adobe – Event Propogation