Skip to content

Android 消息机制 -- HandlerThread 的实现和应用⚓︎

基于 Android android-14.0.0_r28 的源代码

源码路径

framework/base/core/java/andorid/os/HandlerThread.java.

使用示例⚓︎

// 创建并启动 HandlerThread 线程,内部会创建 Looper
HandlerThread handlerThread = new HandlerThread("thread-name");
handlerThread.start();

// 使用 handlerThread 的 Looper 创建 Handler
Handler handler = new Handler(handlerThread.getLooper());

// 使用 handler 发送消息
handler.post(new Runnable() {

        @Override
        public void run() {
            System.out.println("current thread id = " + Thread.currentThread().getId());
        }
    });

源码实现⚓︎

创建 Looper 对象⚓︎

run
public void run() {
    mTid = Process.myTid();
    Looper.prepare();
    synchronized (this) {
        mLooper = Looper.myLooper();
        notifyAll(); // Looper 创建成功,唤醒
    }
    Process.setThreadPriority(mPriority); // 设置优先级,默认值是 Process.THREAD_PRIORITY_DEFAULT 优先级
    onLooperPrepared();  // 可通过覆写,实现自己的逻辑
    Looper.loop();   //进入循环模式
    mTid = -1;
}

获取 Looper 对象⚓︎

getLooper
public Looper getLooper() {
    // 线程未启动或者已经退出,直接返回 null
    if (!isAlive()) {
        return null;
    }

    boolean wasInterrupted = false;

    // 线程已经启动,等待 looper 对象创建
    // If the thread has been started, wait until the looper has been created.
    synchronized (this) {
        while (isAlive() && mLooper == null) {
            try {
                wait(); //等待 Looper 创建
            } catch (InterruptedException e) {
                wasInterrupted = true;
            }
        }
    }

    /*
    * We may need to restore the thread's interrupted flag, because it may
    * have been cleared above since we eat InterruptedExceptions
    */
    // 前面可能吃掉了 InterruptedException 在这吐出来
    if (wasInterrupted) {
        Thread.currentThread().interrupt();
    }

    return mLooper;
}

退出⚓︎

通过调用 looper 的对应的退出方法

 public boolean quit() {
    Looper looper = getLooper();
    if (looper != null) {
        looper.quit();
        return true;
    }
    return false;
}

public boolean quitSafely() {
    Looper looper = getLooper();
    if (looper != null) {
        looper.quitSafely();
        return true;
    }
    return false;
}