Originally posted this article on the Wedding Party tech blog

Mobile devices are getting pretty fast, but they aren’t infinitely fast yet. If you want your app to be able to do any serious work without affecting the user experience by locking up the interface, you’ll have to resort to running things in parallel. On Android, this is done with “threads”.

Grab yourself a cup of coffee and read this post line by line. I’ll introduce you to the concept of threads, talk about how Java uses threads and explain how “Handlers” in Android help with threading.

Whenever you want to do asynchronous/parallel processing, you do it with threads.

Threads you say ?

A thread or “thread of execution” is basically a sequence of instructions (of program code), that you send to your operating system.

Multi-threaded process
Image Courtesy: Wikipedia.

“Typically” your CPU can process one thread, per core, at any time. So a multi-core processor (most Android devices today) by definition can handle multiple-threads of execution (which is to say, they can do multiple things at once).

Truth to multi-core processing and single-core multitasking

I say “typically” because the corollary to the above statement is not necessarily true. Single-core devices can “simulate” multithreading using multitasking.

Every “task” that’s run on a thread can be broken down into multiple instructions. These instructions don’t have to happen all at once. So a single-core device can switch to a thread “1” finish an instruction 1A, then switch to thread “2” finish an instruction 2A, switch back to 1 finish 1B, 1C, 1D, switch to 2, finish 2B, 2C and so on…

This switching between threads happens so fast that it appears, even on a single-core device, that all the threads are making progress at exactly the same time. It’s an illusion caused by speed, much like Agent Brown appearing to have multiple heads and arms.

dogde bullets like your agent brown

Now on to some code.

Threads in core Java

In Java, when you want to do parallel processing, you execute your code in a Runnable either by extending the Thread class or implementing the Runnable interface

// Version 1
public class IAmAThread extends Thread {
    public IAmAThread() {
        super("IAmAThread");
    }

    @Override
    public void run() {
        // your code (sequence of instructions)
    }
}
// to execute this sequence of instructions in a separate thread.
new IAmAThread().start();

// Version 2
public class IAmARunnable implements Runnable {
    @Override
    public void run() {
        // your code (sequence of instructions)
    }
}
// to execute this sequence of instructions in a separate thread.
IAmARunnable myRunnable = new IAmARunnable();
new Thread(myRunnable).start();

Both of these approaches are fundamentally very similar. Version 1 involves creating an actual thread while Version 2 involves creating a runnable, which in-turn has to be called by a Thread.

Version 2, is generally the preferred approach (and is a much larger subject of discussion, beyond the scope of this post).

Threads in Android

Whenever your app starts up in Android, all components are run on a single primary thread (by default) called the “main” thread. The primary role of this thread though, is to handle the user interface and dispatch events to the appropriate widgets/views. For this reason, the main thread is also referred to as the “UI” thread.

If you have a long running operation on your UI thread, the user interface is going to get locked up until this operation is complete. This is bad for your users! That’s why it’s important to understand how threads work in Android specifically, so you can offload some of the work to parallel threads. Android is pretty merciless about keeping things off the UI thread. If you have a long running operation on the UI thread you’re probably going to run into the infamous ANR that will conveniently allow your users to kill your app!

Now Android is all Java, so it supports the usage of the core Java Thread class to perform asynchronous processing. So you could use code very similar to the one shown in the “Threads in Java” section above, and start using threads in Android right away. But that can be a tad bit difficult.

Why is using core Java threads in Android difficult?

Well, parallel processing is not as easy as it sounds because you have to maintain “concurrency” across the multiple threads. In the words of the very wise Tim Bray:

ordinary humans can’t do concurrency at scale (or really at all) …

Specifically for Android, the following is additionally cumbersome:

  1. Synchronization with the UI thread is a major PITA (you typically want to do this, when you want to send progress updates to the UI, for your background operation)
  2. Things change even more weirdly with orientation/configuration changes because an orientation change causes an activity to be recreated (so background threads may be trying to change the state of a destroyed activity, and if the background thread isn’t on the UI thread, well that complicates things even more because of point 1).
  3. There’s also no default handling for thread pooling
  4. Canceling thread actions requires custom code

Arr…ok, so how DO we do parallel processing in Android?

Some (in)famous Android constructs you’ve probably come across:

  1. Handler

    This is the subject of our detailed discussion today

  2. AsyncTask

    Using AsyncTasks are truly the simplest way to handle threads in Android. That being said, they are also the most error prone.

  3. IntentService

    It requires more boiler plate code, but this is generally my preferred mechanism for off-loading long-running operations to the background. Armed with an EventBus like Otto, IntentServices become amazingly easy to implement.

  4. Loader

    These are geared more towards performing asynchronous tasks, that have to deal with data from databases or content providers.

  5. Service (honorable mention)

    If you’ve worked with Services closely, you should know that this is actually a little misleading. A common misconception is that Services run on the background thread. Nope! they “appear” to run in the background because they don’t have a UI component associated with them. They actually run on the UI thread (by default)…. So they run on the UI thread by default, even though they don’t have a UI component?

programmer life gif
Naming has never been Google's strong suit. ActivityInstrumentationTestCase ... wait for it .... 2! Spinner anyone?

If you want your service to run on a background thread, you’ll have to manually spawn another thread and execute your operations in that thread (similar to an approach discussed above). Really you should just use IntentServices but that is a subject for another post.

Android Handlers:

From the not-so-dummy-friendly Android developer documentation for Handlers:

A Handler allows you to send and process Message and Runnable objects associated with a thread’s MessageQueue. Each Handler instance is associated with a single thread and that thread’s message queue. When you create a new Handler, it is bound to the thread/message queue of the thread that is creating it – from that point on, it will deliver messages and runnables to that message queue and execute them as they come out of the message queue.

picture from a dev

To understand that better, you probably need to know what Message Queues are.

Message Queues:

Threads basically have something called a “Message Queue”. These message queues allow communication between threads and is a sort of pattern, where control (or content) is passed between the threads.

It’s actually a wonderful name, because it’s exactly just that: a queue of messages or sequence of instructions, for the thread, to perform one by one. This additionally allows us to do two more cool things:

  • “schedule” Messages and Runnables to be executed at some point in the future
  • enqueue an action to be performed on a different thread other than your own

Note: when I mention ‘message’ from here onwards, it’s the same as a runnable object or a sequence of instructions.

So going back to Handlers in Android…. if you read and pause at every single line, the docs make much more sense now:

A Handler allows you to send and process Message and Runnable objects associated with a thread’s MessageQueue.

So, a handler allows you to send messages to a thread’s message queue. check ✔ !

Each Handler instance is associated with a single thread and that thread’s message queue.

A handler can only be associated with a single thread. ✔

When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it

So, which thread is a handler associated with? The thread that creates it. ✔

– from that point on, it will deliver messages and runnables to that message queue and execute them as they come out of the message queue.

Yeah yeah we already know that. Moving on…

Tip: Here’s something you probably didn’t know : in Android, every thread is associated with an instance of a Handler class, and it allows the thread to run along with other threads and communicate with them through messages.

Another Tip (if you’ve dealt with the more common AsyncTasks): AsyncTasks use Handlers but don’t run in the UI thread. They provide a channel to talk back to the UI, using the postExecute method.

This is all cool yo, so how do I create them Handlers?

Two ways:

  1. using the default constructor: new Handler()
  2. using a parameterized constructor that takes a runnable object or callback object

What useful methods does the Handler API give me?

Remember:

  • Handlers simply send messages or “posts” to the message queues.
  • They are convenience methods that help syncing back with the UI thread.

If you look at the API for Handlers now, the main methods provided make sense:

  1. post
  2. postDelayed
  3. postAtTime

Code samples:

The examples below are rudimentary, what you actually want to be closely following are the comments.

Example 1: using “post” method of the Handler

public class TestActivity extends Activity {

    // ...
    // all standard stuff

    @Override
    public void onCreate(Bundle savedInstanceState) {

        // ...
        // all standard stuff

        // we're creating a new handler here
        // and we're in the UI Thread (default)
        // so this Handler is associated with the UI thread
        Handler mHandler = new Handler();

        // I want to start doing something really long
        // which means I should run the fella in another thread.
        // I do that by sending a message - in the form of another runnable object

        // But first, I'm going to create a Runnable object or a message for this
        Runnable mRunnableOnSeparateThread = new Runnable() {
            @Override
            public void run () {

                // do some long operation
                longOperation();

                // After mRunnableOnSeparateThread is done with it's job,
                // I need to tell the user that i'm done
                // which means I need to send a message back to the UI thread

                // who do we know that's associated with the UI thread?
                mHandler.post(new Runnable(){
                    @Override
                    public void run(){
                        // do some UI related thing
                        // like update a progress bar or TextView
                        // ....
                    }
                });


            }
        };

        // Cool but I've not executed the mRunnableOnSeparateThread yet
        // I've only defined the message to be sent
        // When I execute it though, I want it to be in a different thread
        // that was the whole point.

        new Thread(mRunnableOnSeparateThread).start();
    }

 }

If I didn’t have a handler object, posting back to the UI thread would have been pretty tricky.

Example 2: using postDelayed

In a recent feature for Wedding Party, I had to emulate the auto-complete functionality with an EditText. Every change in text triggered an API call to retrieve some data from our servers.

I wanted to reduce the number of API calls shot out by the app, so I used the Handler’s postDelayed method to achieve this.

This example doesn’t focus on parallel processing, but rather the ability for the Handler to function as a Message Queue and schedule messages to be executed at some later point in the future

// the below code is inside a TextWatcher
// which implements the onTextChanged method
// I've simplified it to only highlight the parts we're
// interested in

private long lastChange = 0;

@Override
public void onTextChanged(final CharSequence chars,
                          int start, int before, int count) {

        // The handler is spawned from the UI thread
        new Handler().postDelayed(

            // argument 1 for postDelated = message to be sent
            new Runnable() {
                @Override
                public void run() {

                    if (noChangeInText_InTheLastFewSeconds()) {
                        searchAndPopulateListView(chars.toString());  // logic
                    }
                }
            },

            // argument 2 for postDelated = delay before execution
            300);

        lastChange = System.currentTimeMillis();
}


private boolean noChangeInText_InTheLastFewSeconds() {
    return System.currentTimeMillis() - lastChange >= 300
}

I leave the “postAtTime” as an exercise for the reader. Got a grip on Handlers? Happy threading!

Follow the discussion on Hacker News or Reddit or Google Plus.