# Internals of HandlerThread in Android

In previous parts, we've delved into `Handler`, `Looper` and `Message`, understanding their roles in enabling code execution within a specified thread and facilitating safe communication between threads.

The `HandlerThread` class combines these concepts, simplifying the acquisition of `Looper` and `Handler` objects. In this article, we'll explore the implementation of `HandlerThread` referencing some AOSP code examples.

## Internals of HandlerThread
[`HandlerThread`](https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/core/java/android/os/HandlerThread.java;drc=be9f42d83645781b78f9448475156ad44bec23a8) extends the `Thread` class, providing additional functionality for initializing a Looper and Handler for the associated thread.

Here's the class definition:
```java
/**
 * A {@link Thread} that has a {@link Looper}.
 * The {@link Looper} can then be used to create {@link Handler}s.
 * <p>
 * Note that just like with a regular {@link Thread}, {@link #start()} must still be called.
 */
public class HandlerThread extends Thread {
    // SajalRG: Implementation details...
}
```
UML class diagram of `HandlerThread` is shown below:
![class diagram handler](//www.plantuml.com/plantuml/svg/NP1D2i8m48NtEKN0ZIAzG71HN2cuADWBH3Dg83zrcWX5lRiCaq3hAfFlJTxBJ3icZIbx9wvEZwFi7mZQoBUGSeivh3TAlg8ruYjAmq47um1dVVuKum2e99z4UckKj25HtQ6DQDDKGUEBXQfUVrbqlKDYDu9S5Sp1_9BKkSapsqJe4gC37IewwnkuYOGz2mkheo65_xQAWSCwX44Za5J7BnFlFaspN88GBGIJlVi1)

As demonstrated, `HandlerThread` essentially functions as a regular Java thread with added capabilities for constructing Looper and providing access to the Looper and Handler instances.

## Recap: Construction of Looper
Examining the `run()` method of `HandlerThread`, we observe the process of Looper initialization, as discussed in first article of this series.

`Looper.prepare()` will create a new instance and can be called only once inside a Thread. `Looper.loop()` waits for message to appear in MessageQueue and process them. For detailed information and innerworking of this, I suggest to read [this](https://blog.sajalrg.com/looper-handler-in-android-part-1-looper) article.
```java
    @Override
    public void run() {
        mTid = Process.myTid();
        Looper.prepare();
        synchronized (this) {
            mLooper = Looper.myLooper();
            notifyAll();
        }
        Process.setThreadPriority(mPriority);
        onLooperPrepared();
        Looper.loop();
        mTid = -1;
    }
```
## Uses of HandlerThread
Now that we understand what `HandlerThread` is and how it operates, let's explore its practical utility.

#### Example1: Setting's App - WifiDialogActivity.java
In this example, `HandlerThread` is used to obtain a `Handler` object for the underlying Thread.
[View Full Code Here](https://cs.android.com/android/platform/superproject/main/+/main:packages/apps/Settings/src/com/android/settings/wifi/WifiDialogActivity.java;l=133;drc=be23c28ff299dc1143f714dc3fa27507d44fbe72).
```java
        if (mIsWifiTrackerLib) {
            // SajalRG: construct new HandlerThread
            mWorkerThread = new HandlerThread(
                    TAG + "{" + Integer.toHexString(System.identityHashCode(this)) + "}",
                    Process.THREAD_PRIORITY_BACKGROUND);
            mWorkerThread.start(); /* SajalRG: actually starts the thread */
            // SajalRG: other code removed for simplicity
            mNetworkDetailsTracker = FeatureFactory.getFactory(this)
                    .getWifiTrackerLibProvider()
                    .createNetworkDetailsTracker(
                            getLifecycle(),
                            this,
                            new Handler(Looper.getMainLooper()), /* SajalRG: passing handler for main looper */
                            mWorkerThread.getThreadHandler(), /* SajalRG: passing handler for the new thread */
                            elapsedRealtimeClock,
                            MAX_SCAN_AGE_MILLIS,
                            SCAN_INTERVAL_MILLIS,
                            mIntent.getStringExtra(KEY_CHOSEN_WIFIENTRY_KEY));
        }
```
#### Example 2: Camera2 App - CaptureModule.java
Here, HandlerThread is utilized to acquire a Looper for creating a new Handler object.[View Full Code Here](https://cs.android.com/android/platform/superproject/main/+/main:packages/apps/Camera2/src/com/android/camera/CaptureModule.java;l=411;drc=00dea6cdc9fa0de0914b9f18c9e05fd414728215).
```java
    @Override
    public void init(CameraActivity activity, boolean isSecureCamera, boolean isCaptureIntent) {
        // SajalRG: other code removed for simplicity
        HandlerThread thread = new HandlerThread("CaptureModule.mCameraHandler");
        thread.start(); /* Thread started */
        /* Create new Handler using looper from handler thread */
        mCameraHandler = new Handler(thread.getLooper());
        // SajalRG: other code removed for simplicity
}
```

## Conclusion
 `HandlerThread` simplifies the creation of a Looper, which otherwise would require manually extending `Thread` class and overloading the `run()` method with similar implementation. Understanding the functionality of `HandlerThread` equips us to leverage its benefits in our projects effectively.

In the next article, we'll address potential memory leak issues with Handler and how to mitigate them.

If you find these articles helpful, please consider liking or commenting to support future content. If you have any questions or topics you'd like covered, feel free to leave a comment below.


