android 多線程 — HandlerThread

今天我們來看一個(gè)簡(jiǎn)單的 HandlerThread,前面我們學(xué)習(xí)過了 handle ,現(xiàn)在再來看 HandlerThread 會(huì)發(fā)現(xiàn)真是簡(jiǎn)單的不得了

HandlerThread 簡(jiǎn)單的說就是 在一個(gè) Thread 里面封裝了一個(gè) looper ,然后啟動(dòng)該 looper ,外接和這個(gè) HandlerThread 的交互都是通過 handle 發(fā)送消息,因?yàn)?HandlerThread 可以返回其虐不的 looper 對(duì)象,然后我們用這個(gè) looper 對(duì)象創(chuàng)建 handle 對(duì)象發(fā)送消息

HandlerThread 的用法


        // 創(chuàng)建 HandlerThread 對(duì)象并啟動(dòng) HandlerThread 所屬線程,構(gòu)造方法需要傳線程的名字進(jìn)去
        HandlerThread handlerThread = new HandlerThread("AAAAAAAA");
        handlerThread.start();

        // 通過 HandlerThread 對(duì)象內(nèi)部的 looper 構(gòu)建用于通訊的 handle
        Handler otherHandle = new Handler(handlerThread.getLooper()) {
            @Override
            public void handleMessage(Message msg) {
                if (msg.what == 1) {
                    Log.d("AAA", Thread.currentThread().getName() + "接受消息" + System.currentTimeMillis());
                }
            }
        };

        // 執(zhí)行線程間通訊任務(wù)
        otherHandle.sendMessage(Message.obtain());

        // 不需要了就關(guān)閉線程,
        handlerThread.quit();
        // handlerThread.quitSafely();

大家要是吧前面我說 handle 的那篇搞明白,這 HandlerThread 的使用實(shí)在不是要太簡(jiǎn)單了

看看源碼吧


其實(shí)猜都能猜到的,這是 HandlerThread 聲明的成員變量

public class HandlerThread extends Thread {
    int mPriority;
    int mTid = -1;
    Looper mLooper;
    private @Nullable Handler mHandler;
{

這是核心 run 方法

    public void run() {
        mTid = Process.myTid();
        Looper.prepare();
        synchronized (this) {
            mLooper = Looper.myLooper();
            notifyAll();
        }
        Process.setThreadPriority(mPriority);
        onLooperPrepared();
        Looper.loop();
        mTid = -1;
    }

在線程啟動(dòng)時(shí)把 looper 消息隊(duì)列跑起來

有意思的地方來了

    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 {
                    // 會(huì)阻塞
                    wait();
                } catch (InterruptedException e) {
                }
            }
        }
        return mLooper;
    }

大家注意 getLooper() 方法是給別的線程調(diào)用的,因?yàn)?handle 的構(gòu)造方法不能接受 null 的 looper 對(duì)象,要不會(huì)拋異常,所以這里在其他線程獲取 HandlerThread 的 looper 對(duì)象時(shí),若是發(fā)現(xiàn)此時(shí) looper 對(duì)象是 null 的,那么就會(huì)阻塞調(diào)用 getLooper() 方法的外部線程。

直到 run 的初始化同步代碼段跑完,此時(shí) looper 初始化完成,會(huì)主動(dòng)喚醒所有阻礙在 looper 對(duì)象身上的 線程,我們?cè)賮砜纯?HandlerThread 的run 方法

    @Override
    public void run() {
        mTid = Process.myTid();
        Looper.prepare();
        synchronized (this) {
            mLooper = Looper.myLooper();
            // 主動(dòng)喚醒所有阻礙在 looper 對(duì)象身上的 線程
            notifyAll();
        }
        Process.setThreadPriority(mPriority);
        onLooperPrepared();
        Looper.loop();
        mTid = -1;
    }

好了,HandlerThread 很簡(jiǎn)單的,這里就基本完事了。我們看 HandlerThread 源碼一定要理解 HandlerThread 為啥要 wait,什么時(shí)候 notifyAll 。這個(gè)是 HandlerThread 里面最值得學(xué)習(xí)的點(diǎn),學(xué)會(huì)了很有用的。

參考資料


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

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

  • 一、Android中的HandlerThread 1.1 主要作用 每隔幾秒鐘更新數(shù)據(jù)或圖片等。 1.2 原理 繼...
    Marker_Sky閱讀 12,043評(píng)論 0 9
  • Android Handler機(jī)制系列文章整體內(nèi)容如下: Android Handler機(jī)制1之ThreadAnd...
    隔壁老李頭閱讀 8,393評(píng)論 8 57
  • 第5章 多線程編程 5.1 線程基礎(chǔ) 5.1.1 如何創(chuàng)建線程 在java要?jiǎng)?chuàng)建線程,一般有==兩種方式==:1)...
    AndroidMaster閱讀 1,921評(píng)論 0 11
  • 為某研究生朋友作: 程浩曾說,一個(gè)人的成長(zhǎng),總是跟另一個(gè)人有關(guān)?!岸ⅰ钡哪贻p人,如果提起跟他有關(guān)的人,除了家...
    框框之上閱讀 944評(píng)論 0 4
  • 今年過的年,電話、視頻貌似是歷年來搞得最多的一回。晨間是與女神家人們視頻,然後看著女神跟俺父母打電話。 上班還算中...
    阿飛閱讀 218評(píng)論 0 1

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