Preface

If you are an Android developer, I can say with surety you have used Handler directly or indirectly. A question arises do you understand it in depth? Let’s go back to basics and learn in and out of Handler. Basic understanding of Java threads and generics is expected. For naive to experienced developers, this article aims to cover something for everyone. If you learn at least one new thing from this article, do share in comments. I will be glad to know.

Like my other posts, it is also going to be a long one. Grab a Coffee, Tea, Beer, Kahwah OR anything which can make you sit for a while.

What is Handler?

First thing first, Handler is not related to UI. Read last line again.Before I jump into Handler business, let me make a statement.

Most of UI based operating systems are single threaded.** **Means, only one thread is permitted to touch User interface -> drawing on the canvas. This choice is made to keep things simple and avoid complicacy. Few attempts have been made in past to make UI multi-threaded but failed because of confusing response to users, race condition, deadlock and few other problems. Android handles some of UI load to other thread for caching and passing commands to GPU which is not in scope of this article.

Android is a single threaded UI framework. We all know there is one UI thread also known as Main thread responsible for drawing. If you touch UI in any other thread, you meet CalledFromWrongThreadException ; Therefore most of the developers have used Handler to post on UI thread using:

    view.post(() -> {
        // do UI stuff
    });
    handler.post(() -> {
        // do UI stuff
    });

Are both ways identical? You will understand by the end of this article.

But what is post doing here? How does it work internally? Why is it even needed? What are the tips and tricks? Let’s begin the ride.

Thread Communication:

Suppose you have two threads, A and B. How will you facilitate communication between them? Consider classical producer-consumer example. A consumer can only consume after the producer has produced. All other times, it has to wait. There are ways like custom flag with an infinite loop, wait/notify, blocking queue etc. I understand this is Java 101. I would like to point it is what makes the basis for Handler.

First definition of Handler: It is the Android way of Thread communication. You use Handler to order threads to perform the desired action. Any thread can be used with Handler way with a small ceremony.

New developers face this issue, you might have faced as well: Can’t create handler inside thread that has not called Looper.prepare()

May of us have copied the following code:

              Looper.prepare();
     
              mHandler = new Handler() { 
                  @Override 
                  public void handleMessage(Message msg) { 
                      // process incoming messages here 
                  } 
              }; 
     
              Looper.loop();

It worked like magic but I always had some itch what the heck it is!

I must admit, this is one of the rare scenarios when I admire Android(while most devs hate this implementation). Usually, I say Android is developed based on what Youtube and Gmail apps demand where it should be vice-versa. Handler is a really clever mechanism of thread communication they have created. They allow threads to switch task and it does not seem like heavy thread work. It appears natural(to me OR I have just accepted the reality of life). Let me try to shed some light.

Suppose you do not have Handler and you are writing a library to make threading easy with following requirements:

  1. A developer must be able to run any piece of code in any thread
  2. A developer must be able to run any piece of code in a thread of their choice
  3. A developer must be able to run any piece of code in a thread of their choice in any class they need (don’t worry you will understand soon)
  4. Make point 2/3 as easy as possible

Run any piece of code in any thread

If not Handler, I will give a shot using ThreadPool and Runnable/Callable. I think this should suffice and does not deserve explanation here. If you want to share a better way, feel free to leave a note OR comment.

Run any piece of code in a thread of their choice

One solution is we can have our own ThreadFactory and spawn a thread as needed. We can have BlockingQueue<Command> attached to each Thread spawned and we can post our custom Command object every-time we need to do something in that particular thread.

Let’s say we spawned a thread named NetworkThread **which accepts only **NetworkCommand. Consider this shitty piece of code:

    Thread networkThread = 
    Thread(){
        @Override
        
    run() {
            BlockingQueue<NetworkCommand> queue = 
    ArrayBlockingQueue<NetworkCommand>();
            
    (isRunning) {
                NetworkCommand command = queue.take();
                
    }
        }
    };
    networkThread.setName(
    );
    networkThread.start();

    Where,
    public void execute(){ runnable.run(); }

Similarly, you can spawn as many Threads you need and point 2 is taken care. We can run any piece of code using our **NetworkCommand **which can have Runnable/Callable or any other interface.

Run any piece of code in a thread of their choice in any class they need which is readable

In point 2 solution, developers can call queue their Command from any class and they will get callback in NetworkThread. Point 3 is partially taken care as well.

There are a few small problems here:

  1. It is not readable when many Runnable are queued in callers class and it reads ugly
  2. Ugly
  3. Ugly
  4. What if you want to pass anything other than heavy Runnable, for e.g an int representing data Loaded signal
  5. How do you identify by just reading which Runnable is called in which thread? You might need to invent your own way, Annotation is one solution and comment is other. // Many devs: Sorry what is a comment?
  6. Ugly
  7. Many other issues you will encounter OR requirements you need to fulfill

How about we create 3 classes

  1. A class which takes care of Thread and Looping through Blocking Queue
  2. Generic Command class with the capability of carrying different type of data [You create these objects and consume]
  3. A class you can attach your command to a destination [Each command has a target where the command will be received]. You send your commands to this class and it adds these commands to blocking queue under the hood. This allows the possibility of queuing commands with delay and other cool functionalities.
  4. First class loops and calls Target class (3) of command
  5. You can create multiple objects of Target class(3) and it appears they are part of Worker Thread

In a nutshell, we just discussed the architecture of Handler.

Let’s just say Android framework devs realized very early they will be using one Thread at a lot of placed and they need to make spaghetti code calling everything from everywhere. They came up with solution for Point 3 & Point 4 and architected it in Handler, Looper and Message.

Summary of Part 1

To maintain the requirement of passing work from different threads and ensuring it feels natural and easy to understand, Android framework devised this mechanism of passing messages around and used it like no tomorrow. They created a class which runs on any thread of your choice and loops infinitely unless you say otherwise. Now you understand why it is called Looper. It is similar to blocking queue looping. Every message it receives has a target attached to it which handles the command, they named it Handler. Every command is called Message, I am sure the author does not remember why the name.

Simple requirement is Handler cannot be instantiated without Looper. After all, it needs that queue. If the Thread you want to use has its Looper, you can create Handler with

    Handler(){
        @Override
        
    handleMessage(Message msg) {
            
    .handleMessage(msg);
        }
    };

If you run this code in UI thread, it will execute properly and magically UI thread looper (queue) will be attached to myHandler. How does it happen?

Handler internally calls

    mLooper = Looper.myLooper();

which uses ThreadLocal [One object per Thread]

/**
 * Return the Looper object associated with the current thread.  Returns
 * null if the calling thread is not associated with a Looper.
 */
public static @Nullable Looper myLooper() {
    return sThreadLocal.get();
}

and if it does not find, you meet RuntimeException

// From handler constructor
mLooper = Looper.myLooper();
if (mLooper == null) {
    throw new RuntimeException(
        "Can't create handler inside thread that has not called Looper.prepare()");
}

It very very simple (like Principle and Principal spelling, you know it still you confirm with Google)

So your normal thread does not have Looper associated with it. Simple, attach a looper with prepare:

// You call this public method which internally calls another prepare
public static void prepare() {
    prepare(true);
}

private static void prepare(boolean quitAllowed) {
    if (sThreadLocal.get() != null) {
        throw new RuntimeException("Only one Looper may be created per thread");
    }
    sThreadLocal.set(new Looper(quitAllowed));
}

Once prepared you can create a new Handler Object and it will not crash with Runtime exception. Following code in your run method:

     Looper.prepare();
 
          mHandler = new Handler() { 
              @Override 
              public void handleMessage(Message msg) { 
                  // process incoming messages here 
              } 
          };

Now you attached a looper (queue) and created Handler as well. What is missing? It is like politicians promising in the political memorandum and never achieving any result. We forgot the main part, execution.

We attached the looper and assigned a Handler which can receive callbacks but we forgot to loop through the messages which is fairly simple with loop method

         Looper.prepare();
 
          mHandler = new Handler() { 
              @Override 
              public void handleMessage(Message msg) { 
                  // process incoming messages here 
              } 
          }; 
 
          Looper.loop();

Loop method says:

/**
 * Run the message queue in this thread. Be sure to call
 * {@link #quit()} to end the loop.
 */
public static void loop() {
...
...
...
for (;;) {
...
...
}
...
...
}

It has an infinite loop which simply waits for messages (remember blocking queue) and calls the message target which is Handler.

You can attach as many Handlers as you want to your thread which has Looper. I leave that as an exercise for you.

HandlerThread

The above thread we saw which has looper and handler can be called HandlerThread. One day Android framework devs realized this small ceremony can be offered as Utility and they created HandlerThread (literally the name).

If you need a worker thread which should have looper attached to it, you can use this utility. It does not save you much code but it is a decent wrapper above looper API. You need to call:

HandlerThread mHandlerThread = new HandlerThread("CustomName");
mHandlerThread.start();
handler = new Handler(mHandlerThread.getLooper()) {}

And you have another worker thread ready which is capable of queuing messages and running in background aligned to Android way.

Tip

In my all apps, I have one worker thread which I create using HandlerThread. I use it everywhere UI thread can’t be used for small task.
Note: All requests to this are queued as per Handler looper contract, so I choose it explicitly for tasks which can be queued.


Message

Is there anything special about Message? Android framework uses it extensively inside. However, it has a few more use cases like IPC which we will cover sometime later. Important to know in context of this article is Message has a cached queue inside. You should not use plain constructor.

/** Constructor (but the preferred way to get a Message is to call {@link #obtain() Message.obtain()}).
*/
public Message() {
}

I find it weird API (did I just define the whole Android?). if something is Public, do not write preferred way. It would have been better if they had made it non-public(IMO). Life is good when binary. When we are in May be dilemma, we never enjoy anything.

Obtain method maintains a pool and reuses objects when possible.

/**
 * Return a new Message instance from the global pool. Allows us to
 * avoid allocating new objects in many cases.
 */
public static Message obtain() {}


Tip

There is a small catch here, Message object has a limited life. Once you receive it in your Handler and execution returns from there, Looper will mark message unused and recycle.

* Recycles a Message that may be in-use.
 * Used internally by the MessageQueue and Looper when disposing of queued Messages.
 */
void recycleUnchecked() {}

Once message is recycled, it can be reused again when next time you call Obtain. So if you cache your message and do some long running task before you process your message, there is a possibility that it is recycled and data is cleared. Dare to debug? Welcome to threading world!

Solution, Whenever you want to consume message with some delay(not instant), use copy:

Message copy = Message.obtain(msg);


Summary

Handler, Message, Looper all combined help you easy threading in Android. This might not be the perfect solution but one of my favorite from the framework. Message is a command with data which recycles itself. Handler is the place where you handle messages and take action. Looper simply is an infinite loop which delivers messages to Handlers. You can attach multiple Handlers to a Looper and there is one looper per thread. You can either call Looper.prepare() OR use HandlerThread utility. Main thread initializes its Handler as soon it starts.

Back to question:

view.post(() -> {
    // do UI stuff
});
handler.post(() -> {
    // do UI stuff
});

Are both ways identical? They are not identical but close. A minor difference is View.post will queue request if View is not attached and handler will immediately post to UI thread queue. Using the wrong way might lead to difficult to reproduce bugs. You know what is happening under the hood.

Chapter 2, Handler and IPC, check here.

Subscribe to newsletter and keep learning good stuff

Email

👉 If you like article, click on ♥️ recommend and share on social 👥 media.
👉 Feel free to comment 💬
👉 Follow me 👀 for the more interesting articles. Twitter Medium
👉 Subscribe to newsletter and keep learning