# Looper, Handler in Android Part 2 - Handler

This article is a continuation of our exploration into the Android's Looper and Handler. If you haven't read [part 1](https://blog.sajalrg.com/looper-handler-in-android-part-1-looper) yet, I recommend revisiting it, as we won't be revisiting those concepts here. In this post, we will look at `Handler` class and its relationship with `Looper` and `Message` classes.

## Construction of Handler
Just as `Looper` in Android is linked to a single thread, it's important to note that a `Handler` is similarly tied to a single `Looper`. However, unlike the `Looper` you can create multiple objects of the `Handler` class within the same thread.

Application developers have two constructors at their disposal for creating a new Handler class:
```java
public Handler (Looper looper)
public Handler (Looper looper, Handler.Callback callback)
```
> Note: Two additional public constructors, `public Handler()` and `public Handler(Handler.Callback callback)`, are now deprecated. If you encounter these constructors or choose to use them for some reason, be aware that they internally use the looper obtained via the `Looper.myLooper()` method.

Here is the actual constructor of the handler, not accessible to app developers. I'm presenting it here to shed light on the inner workings of the handler:
```java
public Handler(@NonNull Looper looper, @Nullable Callback callback, boolean async, boolean shared) {
    mLooper = looper;
    mQueue = looper.mQueue;
    mCallback = callback;
    mAsynchronous = async;
    mIsShared = shared;
}
```
> Note: This multipart article won't cover the details of `mAsynchronous` and `mIsShared`.

## Message and Callback classes
Before comprehending the role of the Handler, let us examine the definitions of the `Handler.Callback` and `Message` classes

### 1. `Handler.Callback`

The `Callback` interface is defined inside `Handler` class as follows:
```java
public interface Callback {
    /**
    * @param msg A {@link android.os.Message Message} object
    * @return True if no further handling is desired
    */
    boolean handleMessage(@NonNull Message msg);
}
```

### 2. `Message`
The [`Message`](https://developer.android.com/reference/android/os/Message) class has various fields and methods, but for our use case we'll focus on a subset of those:
```java
public final class Message implements Parcelable {
    /**
     * User-defined message code so that the recipient can identify
     * what this message is about. Each {@link Handler} has its own name-space
     * for message codes, so you do not need to worry about yours conflicting
     * with other handlers.
     */
    public int what;

    /**
     * arg1 and arg2 are lower-cost alternatives to using
     * {@link #setData(Bundle) setData()} if you only need to store a
     * few integer values.
     */
    public int arg1;

    /**
     * arg1 and arg2 are lower-cost alternatives to using
     * {@link #setData(Bundle) setData()} if you only need to store a
     * few integer values.
     */
    public int arg2;

    /**
     * An arbitrary object to send to the recipient.  When using
     * {@link Messenger} to send the message across processes this can only
     * be non-null if it contains a Parcelable of a framework class (not one
     * implemented by the application).   For other data transfer use
     * {@link #setData}.
     *
     * <p>Note that Parcelable objects here are not supported prior to
     * the {@link android.os.Build.VERSION_CODES#FROYO} release.
     */
    public Object obj;

    @UnsupportedAppUsage
    /*package*/ Handler target;

    @UnsupportedAppUsage
    /*package*/ Runnable callback;
}
```

## Relationship between Handler, Message and Looper
Handler is used to interact with the `Message` loop i.e. `Looper.loop()`.

In [part 1](https://blog.sajalrg.com/looper-handler-in-android-part-1-looper), we delved into a high-level understanding of the `Looper.loop()` method. Now, let's take a close look at the implementation of this method.
 
```java
public static void loop() {
    final Looper me = myLooper();
    if (me == null) {
        throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
    }
    /* << unrelated code removed for comprehension >> */
    for (;;) {
        if (!loopOnce(me, ident, thresholdOverride)) {
            return;
        }
    }
}

private static boolean loopOnce(final Looper me, final long ident, final int thresholdOverride) {
    Message msg = me.mQueue.next(); // might block
    if (msg == null) {
        // No message indicates that the message queue is quitting.
        return false;
    }
    /* << unrelated code removed for comprehension >> */
    try {
        msg.target.dispatchMessage(msg);
        if (observer != null) {
            observer.messageDispatched(token, msg);
        }
        dispatchEnd = needEndTime ? SystemClock.uptimeMillis() : 0;
    } catch (Exception exception) {
        /* << unrelated code removed for comprehension >> */
        throw exception;
    }
    /* << unrelated code removed for comprehension >> */
}
```
> Note: I've included only the essential code for our comprehension, but you can refer to the complete code [here](https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/core/java/android/os/Looper.java).

Here, `msg.target` has reference to the instance of the `Handler` class and the `Looper` calls the `dispatchMessage()` method of the `Handler` class in each loop. This occurs inside the `Thread` where the `Looper` is looping.
Same can be visualised in below sequence diagram
![uml sequence diagram of looper.loop method](https://www.plantuml.com/plantuml/svg/RP11ReGm34NtFeMNiE02Q8HcsKhjebBd05RYTY914YLErTw-eG6BYjd44BxVmxvceIHbcI7MweoBv0LlcHF074A4btfmmc72LywPFlcjSE4HFNzBrmCPSLyaZ2sdx__I0BVS64_axSnfnCi5JU8rU6zNs3L2ZzEab3qFMyMXCbRMY8cb98_EPo5l-6o88Qy_g9qwm56-jAkZSu_1Ld5GgcgVToie_hGWilOz_3rtsuSU3ed6RJFlM5NhrWzcwt8aCVSjKqTxE5jj-mXfmRMVn0KFba_hj9mbXH_riRS0rtgMPVu5)

By now, we've covered `Looper`, `Handler`, and the `Message` class and have an understanding of the role of the `MessageQueue`.

In the upcoming article, we will consolidate our knowledge gained so far and apply it in real-world scenarios to effectively utilize the `Handler` class. Additionally, we will closely examine the `dispatchMessage()` method to deepen our understanding of its role in the overall process.
