Android HandlerThread

Today I’m going to talk about something I ran into recently that turned out to be very simple, despite initially seeming a little confusing, the Android HandlerThread class.

So, first of all, why did I run into this? Well, basically I’ve been doing some work to improve the multi-threading of one of my applications, by splitting off some of the background work into a number of different threads; and to allow those threads to be easily interacted with, I wanted each of them to have their own Handler.

Now I’d read how to turn a thread into a Handler thread by calling Looper.prepare(), setting up my Handler & then calling Looper.loop(); however this left my thread unable to perform its own background activities and so I ended up creating sub-threads / runnables and things started getting rather messy.

Assuming there must be a better way to do this, I eventually came across HandlerThread, which is described in the Android documentation as:

Handy class for starting a new thread that has a looper. The looper can then be used to create handler classes. Note that start() must still be called.

Now, in retrospect that actually seems quite clear – so I’m hoping that by writing this post, I’m not just exposing my stupidity – but initially I was a little unsure what it meant and how to use it.

Anyway, long story short, after some searching and some experimentation, I came across the correct way to use it. Which is, unsurprisingly, very similar to how it’s described above:

First of all you create and start a HandlerThread, which creates a thread with a Looper:

//Create and start the handler thread - give it a custom name
HandlerThread handlerThread = new HandlerThread("MyHandlerThread");
handlerThread.start();

You then get the Looper from the HandlerThread as follows:

//Get the looper from the handlerThread
Looper looper = handlerThread.getLooper();

Note that the above method call can return null, in the unlikely event that the HandlerThread not been started or if for any reason isAlive() returns false. Practically I think this is unlikely to happen and I’m not sure if there’s anything sensible to do if it does, so I wouldn’t worry about it too much.

You can then create your Handler, passing in the Looper for it to use

//Create a new handler - passing in the looper for it to use
Handler handler = new Handler(looper);

 
And that’s all there is to it. You’ve now you got your own Handler running in it’s own thread. Simple, right?

And finally, when your thread is finished, you can shut down the HandlerThread as follows:

//Shut down the HandlerThread
handlerThread.quit();

 
Just for completeness, below is an example of a complete class that extends thread and uses a HandlerThread to create a Handler for inter-thread communication. As a side note, it also demonstrates the use of the Handler.Callback interface to save you having to subclass Handler for performing your custom message handling.

package com.stephendnicholas;

import android.os.Handler;
import android.os.Handler.Callback;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;

public class ExampleThread extends Thread implements Callback {

	public static final int CUSTOM_MESSAGE = 1;

	private boolean running = true;

	private final Object mutex = new Object();

	public ExampleThread() {
	}

	@Override
	public void run() {
		// Create and start the HandlerThread - it requires a custom name
		HandlerThread handlerThread = new HandlerThread("MyHandlerThread");
		handlerThread.start();

		// Get the looper from the handlerThread
		// Note: this may return null
		Looper looper = handlerThread.getLooper();

		// Create a new handler - passing in the looper to use and this class as
		// the message handler
		Handler handler = new Handler(looper, this);

		// While this thread is running
		while (running) {

			// TODO - custom thread logic

			// Wait on mutex
			synchronized (mutex) {
				try {
					mutex.wait();
				} catch (InterruptedException e) {
					// Don't care
				}
			}
		}

		// Tell the handler thread to quit
		handlerThread.quit();
	}

	public void shutdown() {
		// Set running to false
		running = false;

		// Wake anyone waiting on mutex
		synchronized (mutex) {
			mutex.notifyAll();
		}
	}

	@Override
	public boolean handleMessage(Message msg) {

		switch (msg.what) {
		case CUSTOM_MESSAGE:
			// TODO - custom logic
			break;

		default:
			// Return false - as we have not handled the message
			return false;
		}

		// Return true - as we have handled the message
		return true;
	}

}

12 Comments

  • 07/12/2011 - 1:33 am | Permalink

    Your example is overly complicated; it appears to start two threads. You really want to extend Handler with your custom handler. Then to initialize it, you’d simply do:

    HandlerThread handlerThread = new HandlerThread(“MyHandlerThread”);
    mHandlerThread.start();

    CustomHandler myHandler = new CustomHandler(mHandlerThread.getLooper());

    Later during shutdown of the process:
    mHandlerThread.quit();

    That eliminates the need for the extra thread, the mutex, and the shutdown() method.

    • 07/12/2011 - 9:00 am | Permalink

      Hi Kenny,

      Thanks for your comment. You’re correct that the example does more than it needs to just to demonstrate the use of HandlerThread. The reason for this is that I wanted to show a complete example (that someone could just copy and paste) of a background thread, with it’s own handler for inter-process communication; as that is how I came to use HandlerThread in the first place. I’ve tried to cover the basic case in the code snippets further up, but apologies if that’s not clear.

    • Samir
      11/17/2011 - 7:22 pm | Permalink

      Stephen, Kenny, I’d really like to undertand a little bit more about your solutions for using HandlerThread.

      Kenny, what do you mean that the example appears to start two threads? You mean one of the threads would be the one created for the “ExampleThread” class and the other one the Handler Thread itself?

      What kind of implementation would the CustomHandler need in order to make it unnecessary to use a extra thread, the mutex() and the shutdown() methods?

      Thank you

  • Bob
    11/11/2011 - 6:15 pm | Permalink

    How will the while loop ever loop around if the mutex is blocked until shutdown is called?

    • 11/18/2011 - 1:53 pm | Permalink

      Hi Bob,

      You’re correct. In the example above, the ExampleThread simply waits on the mutex until shutdown is called. If you were actually implementing something to do something, you’d probably add a call to notify on the mutex in the handleMessage method; to trigger the ExampleThread to do something by running through the loop again.

      A common pattern I use this kind of thing for, is to use the Handler to add work to a queue and then to wake up a worker Thread to process all the things on the queue. When it’s done, it then waits on the mutex until either more work comes in or shutdown is called.

      I was trying to make the example somewhat complete, but also not overcomplicate it too much. Judging from the comments so far, I’m not sure how well I’ve done on that count :)

  • jiayi
    12/08/2011 - 6:04 am | Permalink

    good essay. you explain it in a clear way.

  • Pingback: executing asynchronous task from service in android | PHP Developer Resource

  • Larry Burton
    11/23/2012 - 11:18 pm | Permalink

    Thanks Stephen –

    I knew HandlerThread was what I wanted, but I really didn’t want to have to spend the time to figure out exactly how to use it. This was perfect!

  • Pingback: Looper not called outside the Thread class : Android Community - For Application Development

  • Pingback: Android Loopers:Unable to get messages from UIThread to worker thread : Android Community - For Application Development

  • Hitesh Pamnani
    03/01/2013 - 6:31 am | Permalink

    Hello Stephen!

    Thanks a lot for this awesome concept. I was really trying hard to get something like this, and at last, I found it here. I was trying to use AsyncTask, Handler, Threads, Runnable by all other means. But, your article really made my day. Thanks a lot once again! :)

  • Andrork
    08/16/2013 - 5:37 am | Permalink

    Awesome man! This is the first example I found which just focuses on the essentials. Many bogus/confusing articles out there…

  • Leave a Reply

    Your email address will not be published. Required fields are marked *

    *

    You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>