# Looper, Handler in Android Part 4 - Handler

This is the final article in our series on Introduction Looper and Handler in Android. To fully grasp the concepts discussed here, it's assumed that you have read or are familiar with the content covered in previous parts. If not, I recommend revisiting those articles first.

## Recap of How to Use Handler

Handler can be utilized in two main ways:

1. **Passing Runnable**: Adding or posting operation to be executed directly inside the thread from another thread. This is accomplished using the `post()` method of `Handler`.
  
2. **Sending Message**: Sending a message about an operation that needs to be done inside the thread from another thread. This involves a combination of the `sendMessage()` and `handleMessage()` methods of `Handler`.    

  While we coverted the `post()` method extensively in part3, here we will delve into the `sendMessage()` and `handleMessage()` methods of the `Handler`.
    
## When to use `sendMessage()`
As the name suggests, `sendMessage()` is used to send a `Message` object to a `Handler` and `handleMessage()` will perform certain operation on the received `Message`. The two methods, `sendMessage()` and `handleMessage()`, must always be used in conjunction. If you use`sendMessage()` to send a `Message` to a `Handler`, the `Handler` must also implement its `handleMessage()` to process that message.

Unlike `post()`, which is suitable for executing a block of code, `sendMessage()` is used for reusable pieces of code that need to be handled frequently within your thread. For example, when multiple parts of your code needs to save documents, you can use `sendMessage()` to organize your code more efficiently. All the logic related to file operations will be handled separately, enabling reuse, concurrency, separation of concerns, and synchronous access to the file I/O operations. By passing the path as an argument, the same code can be utilized for multiple other documents, further enhancing its flexibility and maintainability.

> Note: In terms of synchronicity, The `sendMessage()` call itself is asynchronous, non-blocking and can be executed from any thread. The `handleMessage()` method associated with it will always be invoked synchronously and will run on the same thread that the Handler operates on.

## Internals of `sendMessage()`

Internally both `post()` and `sendMessage()` work similarly. The difference lies in how they are handled as seen above. Typically, `post()` is used for running a one-off block of code in another thread (e.g., updating the UI), and `sendMessage()` is used for operations that need to be repeated. However, there is no strict rule in the language construct, and it largely depends on your use case and programming style.

To reiterate, here's an excerpt from the Android documentation of [`Handler`](https://developer.android.com/reference/android/os/Handler)
> The post versions allow you to enqueue Runnable objects to be called by the message queue when they are received; the sendMessage versions allow you to enqueue a Message object containing a bundle of data that will be processed by the Handler's handleMessage(Message) method (requiring that you implement a subclass of Handler).

Similar to `post()`, `sendMessage()` also calls `sendMessageDelayed()` function to add the `Message` to the `MessageQueue` (refer to part 3 for the detailed flow of `post()`). The only difference lies in the `dispatchMessage` method which calls `handleMessage()` instead.

```java
    // SajalRG: adds message to the queue, called from any thread
    public final boolean sendMessage(@NonNull Message msg) {
        return sendMessageDelayed(msg, 0);
    }

    /**
     * Handle system messages here.
     */
   // SajalRG: executed from Looper.loop() inside the thread represented by handler
    public void dispatchMessage(@NonNull Message msg) {
        if (msg.callback != null) {
            handleCallback(msg);
        } else {
            if (mCallback != null) {
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            handleMessage(msg);
        }
    }
```

## Example from AOSP SystemUI
Let's examine an example from AOSP on how this pair can be utilized. We will take a look at the [`CommandQueue`](https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java) class.
> Note: Our objective here is not to delve into the intricacies of the `CommandQueue` class itself. Instead, we aim to focus solely on how it leverages the `sendMessage()` and `handleMessage()` methods. This approach provides insight into real-world usage in larger projects, offering a practical understanding rather than relying on contrived examples.

```java
/**
 * This class takes the functions from IStatusBar that come in on
 * binder pool threads and posts messages to get them onto the main
 * thread, and ...
 */
public class CommandQueue extends IStatusBar.Stub implements
        CallbackController<Callbacks> {
```
In this example, `CommandQueue` also `extends` the `IStatusBar.stub()`, which we can ignore for now but it could be a topic for furture articles on `Binder` and `AIDL`. `CallbackController` is an `interface` which the `CommandQueue` implements, but we won't explore it further in this post.

For our purpose, `CommandQueue` has some methods that are called from other threads, referred to as `binder pool threads`, and it will post the messages onto the main thread.

### Understanding CommandQueue
If you view the `CommandQueue` class from [this link](https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java), you might notice that there is no `sendMessage()` call in the class, even though we are using this as an example for `sendMessage()`.

To understand this, let's look at `Message` class. We partially covered the `Message` class in part 2, please review if you haven't already. Now, let's introduce method `sendToTarget` class which is used here. It internally calls the `sendMessage()` for us. Both approaches are okay.
```java
    /**
     * Sends this Message to the Handler specified by {@link #getTarget}.
     * Throws a null pointer exception if this field has not been set.
     */
    public void sendToTarget() {
        target.sendMessage(this);
    }
```
Also, instead of using `Message.obtain()` to create new `Message`, as we saw in part3, `Handler.obtainMessage()` is used here, which internally does the same. Below is the excerpt from the `Handler` class listing all other possible ways to obtain `Message`.
```java
    @NonNull
    public final Message obtainMessage() {
        return Message.obtain(this);
    }

    /**
     * Same as {@link #obtainMessage()}, except that it also sets the what member of the returned Message.
     * 
     * @param what Value to assign to the returned Message.what field.
     * @return A Message from the global message pool.
     */
    @NonNull
    public final Message obtainMessage(int what) {
        return Message.obtain(this, what);
    }
    
    /**
     * 
     * Same as {@link #obtainMessage()}, except that it also sets the what and obj members 
     * of the returned Message.
     * 
     * @param what Value to assign to the returned Message.what field.
     * @param obj Value to assign to the returned Message.obj field.
     * @return A Message from the global message pool.
     */
    @NonNull
    public final Message obtainMessage(int what, @Nullable Object obj) {
        return Message.obtain(this, what, obj);
    }

    /**
     * 
     * Same as {@link #obtainMessage()}, except that it also sets the what, arg1 and arg2 members of the returned
     * Message.
     * @param what Value to assign to the returned Message.what field.
     * @param arg1 Value to assign to the returned Message.arg1 field.
     * @param arg2 Value to assign to the returned Message.arg2 field.
     * @return A Message from the global message pool.
     */
    @NonNull
    public final Message obtainMessage(int what, int arg1, int arg2) {
        return Message.obtain(this, what, arg1, arg2);
    }
    
    /**
     * 
     * Same as {@link #obtainMessage()}, except that it also sets the what, obj, arg1,and arg2 values on the 
     * returned Message.
     * @param what Value to assign to the returned Message.what field.
     * @param arg1 Value to assign to the returned Message.arg1 field.
     * @param arg2 Value to assign to the returned Message.arg2 field.
     * @param obj Value to assign to the returned Message.obj field.
     * @return A Message from the global message pool.
     */
    @NonNull
    public final Message obtainMessage(int what, int arg1, int arg2, @Nullable Object obj) {
        return Message.obtain(this, what, arg1, arg2, obj);
    }
```
In above code snippet, different signature which allows us to pass additional information to the `Message` are also listed. Here, `what` is primarily used in `handleMessage()` identify which operation to perform.

### Message flow in CommandQueue
Let's explore the `addQsTile` method to explore the message flow. First, the method is called from the binder thread.
```java
    // SajalRG: create new handler using the main looper
    private Handler mHandler = new H(Looper.getMainLooper());
    @Override
    public void addQsTile(ComponentName tile) {
        synchronized (mLock) {
            // SajalRG: get message object and send the message
            mHandler.obtainMessage(MSG_ADD_QS_TILE, tile).sendToTarget();
        }
    }
```
Then, it is handled inside the Handler
```java
    private final class H extends Handler {
        private H(Looper l) {
            super(l);
        }
        // SajalRG: handleMessage is called in conjunction to the sendMessage
        public void handleMessage(Message msg) {
            final int what = msg.what & MSG_MASK;
            // SajalRG: what is used to identify which operation to execute
            switch (what) {
                // SajalRG: other cases
                case MSG_ADD_QS_TILE:
                    // SajalRG: actual operation happening inside the main thread
                    for (int i = 0; i < mCallbacks.size(); i++) {
                        mCallbacks.get(i).addQsTile((ComponentName) msg.obj);
                    }
                    break;
                // SajalRG: other cases
            }
        }
    }
```

## What's next
This post concludes our introduction to `Handler`, `Looper` and `Thread`. I hope you have a clearer understanding of the subject and how they are interconnected at a high level. I'd still like to continue this series addressing some misconceptions I'd come across and answer some frequently asked questions related to this topic. If you have any specific topics or query you'd like me to cover, please feel free to leave a comment.

Your support serves as great encouragement for me to continue creating and sharing content.
