Threads, handlers and AsyncTask: efficient asynchronous programming in Android

When creating Android applications you sometimes need to fetch data from servers, create game event loops or get information from web sites. Since Java’s IO operations are blocking, there is a risk of freezing the application if you try to do these time consuming operations directly in the UI thread. This can result in getting an ANR, which is short for Application Not Responding, a dialog that appears after the application has been frozen for 5 seconds and where the user has the option to kill the entire application.

An obvious solution is to run these operations in a separate thread but when you need to update the UI you can not do this from any other thread then the UI thread or you will run into problems. This is because the UI thread is not thread-safe.

Two Android robots

Android has two main rules for handling threads:

  1. Do not block the UI thread
  2. Do not access the Android UI toolkit from outside the UI thread

These two rules can be conflicting when programming asynchronously, but there are several ways to make sure that these rules are always followed:

  1. Schedule to the UI thread using Android built-in methods
  2. Asynchronous methods
    • AsyncTask is a utility class provided by Android which handles threading for you. Easy to use when a large amount of data needs to be fetched and then displayed in the UI.
  3. Explicit threading
    • Plain Java threads that preforms time consuming tasks and then by using a Handler schedule the task to update the UI to the UI thread.

Schedule to the UI thread using Android built-in methods

There are three built-in methods in Android that can handle the situation when one of your Activity classes are run on or called from a different thread. We can then schedule the UI updates to be run on the UI thread with these three methods below. The Activity or View then works as a handler (more on handlers below) and schedules your runnable to the UI thread:

  • Activity.runOnUiThread(Runnable)
  • View.post(Runnable)
  • View.postDelayed(Runnable, long) //(long = time to scheduling)

Example:

Activity.runOnUiThread(new Runnable() {
	public void run() {
		//Update UI
	}
});

Asynchronous methods – AsyncTask

AsyncTask can be useful in situations when there is a need for getting something from a server or a web page and then show it in the UI as soon as it is finished. When using AsyncTask you usually create an internal class which extends AsyncTask. This class implements mainly two methods, doInBackground and onPostExecute, there are two more that can be implemented for when something needs to be done before the doInBackground method or during its execution as seen in the example below. The three generic arguments for AsyncTask can be changed to whatever is needed for the situation for more details see example below.

Example:

class Async extends AsyncTask{
	//Run on UI thread
	@Override
	protected void onPreExecute(){}
 
	//Run in separate thread
	@Override
	protected Z doInBackground(X input){
		//Do task, like getting info from web
		return result;
	}
 
	//Run on UI thread
	@Override
	protected void onProgressUpdate(Y y){}
 
	//Run on UI thread
	@Override
	protected void onPostExecute(Z result){
		//Do something with data like update UI
	}
}
 
Async task = new Async();
task.execute(X input);

 

The method doInBackground is the only asynchronous method, the other three methods are run on the UI thread and can therefore update the UI. AsyncTask is an easy way for you to do time consuming operations in the background and updating the UI. The big advantage is that you don’t need to handle the threads yourself Android through Java does this for you.

Explicit threading

By using the Java’s Thread and Runnable with Android’s Handler, a simple loop can be created and used for continuously update a process bar, run a game loop or get data from a server without blocking the UI thread.

Handler

Handler is a class from the Android library, it can be used in two main ways: it can handle messages and schedule runnables to the UI thread or it can do the same but schedule them on a different thread. The handler gets bound to the thread in which it is created so if it is created in the UI thread it can be used to schedule tasks for the UI thread within another thread. Examples follow below:

Example on how to create a thread safe loop run in a different thread then the UI thread:

//Create handler in the thread it should be associated with 
//in this case the UI thread
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
	public void run() {
		while(running){
			//Do time consuming stuff
 
			//The handler schedules the new runnable on the UI thread
			handler.post(new Runnable() {
				@Override
				public void run() {
					//Update UI
				}
			});
			//Add some downtime
			try {
				Thread.sleep(100);
			}catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
};
new Thread(runnable).start();

 

Example on how to create an asynchronous thread with similar abilities to AsyncTask, the advantage with this loops is that you can create more than one asynchronous method and it can easily be turned into a loop by inserting a while loop. Everything concerning updating the UI is done in the runnable that the handler, in turn, schedules onto the UI thread:

//Create Handler bound to the UI thread
Handler handler = new Handler();
static public class MyThread extends Thread {
	@Override
	public void run() {
		//Do stuff that takes time
 
		//To be able to update the UI we have to post 
		//the runnable onto the UI thread 
		handler.post(new MyRunnable());
	}
}
 
static public class MyRunnable implements Runnable {
	public void run() {
		//Update the UI
	}
}
 
MyThread thread = new MyThread();
thread.start();

Final thoughts

There are several ways to deal with the issue of updating the UI from a different thread. These examples would solve most of the problems encountered (with a little modification to the code) but I am sure that there are situations where special solutions are needed. However, do keep in mind that the above examples is only needed when updating the UI from any other thread then the UI thread. If you only need a thread doing operations asynchronously that doesn’t involve the UI you can always use normal Java threading.

 

This entry was posted in Uncategorized and tagged , , , , , , . Bookmark the permalink.