返回

Android 源码 HandlerThread 深度剖析

Android

Android中,HandlerThread 主要用于处理长时间运行的任务,比如音频、视频播放,网络请求等。它通过创建一个后台线程(即Looper线程),并在这个线程中创建一个Handler,以便我们可以在主线程中与后台线程进行通信。

HandlerThread 源码的剖析分为以下几个部分:

  1. 类结构 :HandlerThread 的整体结构是什么?它有哪些属性和方法?
  2. 创建线程 :HandlerThread是如何创建后台线程的?它使用了哪些类和方法?
  3. 创建 Looper :HandlerThread是如何创建 Looper 的?它使用了哪些类和方法?
  4. 创建 Handler :HandlerThread是如何创建 Handler 的?它使用了哪些类和方法?
  5. HandlerThread 的生命周期 :HandlerThread 的生命周期是什么样的?它经历了哪些状态?

在本文中,我将详细地分析 HandlerThread 的源码,并通过代码示例来演示如何使用 HandlerThread 来创建后台线程和 Handler。

1. 类结构

HandlerThread 的类结构非常简单,它只有一个公共属性和几个公共方法。

属性

  • mThread: Looper 线程
  • mTid: Looper 线程的 ID
  • mLooper: Looper 对象
  • mHandler: Handler 对象

方法

  • HandlerThread(String name):构造函数,创建一个 HandlerThread 对象。
  • start(): 启动 HandlerThread,创建一个后台线程和 Looper,并创建 Handler。
  • quit(): 退出 HandlerThread,停止后台线程和 Looper,并销毁 Handler。
  • getLooper(): 获取 Looper 对象。
  • getThreadId(): 获取 Looper 线程的 ID。
  • isAlive(): 判断 HandlerThread 是否处于活动状态。
  • join(): 等待 HandlerThread 退出。

2. 创建线程

HandlerThread 使用 android.os.Process 类来创建后台线程。

public HandlerThread(String name) {
    super(name);
    mState = STATE_BEFORE_START;
}

public synchronized void start() {
    if (mState != STATE_BEFORE_START) {
        throw new IllegalStateException(this + " already started.");
    }
    mState = STATE_STARTING;
    mThread = new Thread(this, mName);
    mThread.start();
    while (mState != STATE_STARTED) {
        try {
            wait();
        } catch (InterruptedException e) {
        }
    }
}

start() 方法中,HandlerThread首先检查当前状态是否为 STATE_BEFORE_START,如果不是,则抛出异常。然后,它将状态设置为 STATE_STARTING,并创建一个新的线程,该线程的名称为 mName

public void run() {
    Looper.prepare();
    synchronized (this) {
        mLooper = Looper.myLooper();
        mState = STATE_STARTED;
        notifyAll();
    }
    Looper.loop();
    synchronized (this) {
        mState = STATE_QUIT;
        notifyAll();
    }
}

在新线程中,HandlerThread首先调用 Looper.prepare() 方法,这会创建一个 Looper 对象,并将其设置为当前线程的 Looper。然后,它将状态设置为 STATE_STARTED,并通知主线程,主线程会继续执行。

3. 创建 Looper

HandlerThread 使用 android.os.Looper 类来创建 Looper 对象。

public void run() {
    Looper.prepare();
    synchronized (this) {
        mLooper = Looper.myLooper();
        mState = STATE_STARTED;
        notifyAll();
    }
    Looper.loop();
    synchronized (this) {
        mState = STATE_QUIT;
        notifyAll();
    }
}

run() 方法中,HandlerThread首先调用 Looper.prepare() 方法,这会创建一个 Looper 对象,并将其设置为当前线程的 Looper。然后,它将状态设置为 STATE_STARTED,并通知主线程,主线程会继续执行。

4. 创建 Handler

HandlerThread 使用 android.os.Handler 类来创建 Handler 对象。

public HandlerThread(String name) {
    super(name);
    mState = STATE_BEFORE_START;
}

public synchronized void start() {
    if (mState != STATE_BEFORE_START) {
        throw new IllegalStateException(this + " already started.");
    }
    mState = STATE_STARTING;
    mThread = new Thread(this, mName);
    mThread.start();
    while (mState != STATE_STARTED) {
        try {
            wait();
        } catch (InterruptedException e) {
        }
    }
}

start() 方法中,HandlerThread首先检查当前状态是否为 STATE_BEFORE_START,如果不是,则抛出异常。然后,它将状态设置为 STATE_STARTING,并创建一个新的线程,该线程的名称为 mName

public void run() {
    Looper.prepare();
    synchronized (this) {
        mLooper = Looper.myLooper();
        mState = STATE_STARTED;
        notifyAll();
    }
    Looper.loop();
    synchronized (this) {
        mState = STATE_QUIT;
        notifyAll();
    }
}

在新线程中,HandlerThread首先调用 Looper.prepare() 方法,这会创建一个 Looper 对象,并将其设置为当前线程的 Looper。然后,它将状态设置为 STATE_STARTED,并通知主线程,主线程会继续执行。

5. HandlerThread 的生命周期

HandlerThread 的生命周期有三个状态:

  • STATE_BEFORE_START:HandlerThread 还没有启动。
  • STATE_STARTING: HandlerThread 正在启动。
  • STATE_STARTED: HandlerThread 已经启动。
private static final int STATE_BEFORE_START = 0;
private static final int STATE_STARTING = 1;
private static final int STATE_STARTED = 2;
private static final int STATE_QUIT = 3;

HandlerThread 的生命周期由 start()quit() 方法控制。

public synchronized void start() {
    if (mState != STATE_BEFORE_START) {
        throw new IllegalStateException(this + " already started.");
    }
    mState = STATE_STARTING;
    mThread = new Thread(this, mName);
    mThread.start();
    while (mState != STATE_STARTED) {
        try {
            wait();
        } catch (InterruptedException e) {
        }
    }
}

public void quit() {
    synchronized (this) {
        mState = STATE_QUIT;
        mLooper.quit();
        notifyAll();
    }
}

当调用 start() 方法时,HandlerThread 会创建一个后台线程和 Looper,并创建 Handler。当调用 quit() 方法时,HandlerThread 会停止后台线程和 Looper,并销毁 Handler。