HandlerThread源碼解析

1、HandlerThread 是什么?

它繼承至 Thread,具備線程的特性。它是一個帶有 Looper 的線程,并且該Looper可以被用于創(chuàng)建對應的Handler。

2、HandlerThread的作用是什么?

當一個線程執(zhí)行完一個耗時任務之后,如果想要再執(zhí)行另外一個耗時任務那么就需要重新創(chuàng)建一個新的線程,而多次進行線程的開啟和銷毀的是需要很大的開銷。在一般情況下,線程被開啟之后,也就是run方法會被執(zhí)行,若需要動態(tài)地在執(zhí)行過程做一些其它處理,例如根據(jù)不同的條件執(zhí)行不同的代碼塊,顯然是比較麻煩的。而HandlerThread解決了這個問題,它內(nèi)部維護了一個Looper不斷地去輪訓消息隊列,當需要在子線程做其他操作時,只需要通過綁定的Handler去發(fā)送消息,然后處理即可。

3、HandlerThread的工作原理

HandlerThread 是一個內(nèi)部維護一個 Looper 對象的線程。這樣就省去了創(chuàng)建線程時需要手動的創(chuàng)建 Looper 的麻煩。而已它內(nèi)部使用了
wait() 和 notifyAll() 保證的 Looper 的非空性控制。

3.1、HandlerThread#run()

  • 該方法是一個loop()的死循環(huán),等待消息的到來。
  • Looper.prepare()創(chuàng)建Looer對象并保存到ThreadLocal中。
  • Looper.myLooper()獲取通過preparen()保存的Looper對象。
  • loop()開啟輪訓器輪訓。
public void run() {
    mTid = Process.myTid();
    Looper.prepare();
    synchronized (this) {
        
        mLooper = Looper.myLooper();
        //在這里的 Looper 已經(jīng)創(chuàng)建完畢,通知 getLooper 不需要等待啦。
        notifyAll();
    }
    Process.setThreadPriority(mPriority);
    onLooperPrepared();//空的回調(diào),交由用戶做一些loop()前的準備工作。
    Looper.loop();
    mTid = -1;
}

3.2、HandlerThread#getLooper()

獲取關聯(lián)的Looper對象,可用于外部創(chuàng)建Handler的構(gòu)造參數(shù),該方法中有一個wait()方法,然后在run()中一個notifyAll()方法,他們的作用就是在getLooper時為了保證能正確的獲取到當looper對象,當looper為null,就讓其等待,直到run()方法創(chuàng)建了其Looper對象之后調(diào)用notifyAll喚醒。

public Looper getLooper() {
    if (!isAlive()) {
        return null;
    }
    
    // If the thread has been started, wait until the looper has been created.
    synchronized (this) {
        while (isAlive() && mLooper == null) {
            try {
                wait();
            } catch (InterruptedException e) {
            }
        }
    }
    return mLooper;
}

3.3、移除消息隊列中的消息

//立即退出
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;
}

4、 IntentService 內(nèi)部 HandlerThread 的應用


@Override
public void onCreate() {
    super.onCreate();
    HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
    //開啟線程
    thread.start();
    //getLooper 是一個阻塞方法。
    mServiceLooper = thread.getLooper();
    //Handler 綁定一個通過 HandlerThread 創(chuàng)建的 looper 對象。
    mServiceHandler = new ServiceHandler(mServiceLooper);
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容