Android HandlerThread簡單使用

HandlerThread簡介

HandlerThread繼承了Thread,它是一種可以使用Handler的Thread,它的實現(xiàn)就是在run()方法中通過Looper.prepare()創(chuàng)建消息隊列,并通過Looper.loop()開啟消息循環(huán)。這樣在實際使用中就允許在HandlerThread中創(chuàng)建Handler了。
由于HandlerThread的run()方法是一個無限循環(huán),因此當(dāng)明確不需要使用HandlerThread的時候可以通過Looper的quit()或quitSafely()來終止線程執(zhí)行。

使用Handler

通常我們會在主線程中創(chuàng)建Handler,在子線程中調(diào)用handler.post(runnable)傳遞消息到主線程的消息隊列中處理runnable的run方法.這樣完成了子線程到主線的切換。
在onCreate()方法中

mainHandler = new Handler();

然后在子線程中post

btn_post_to_main_thread.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                Log.d(TAG, "Thread id = " + Thread.currentThread().getId());
                mainHandler.post(runnable);
            }
        }).start();
                
    }
});

runnable

    private Runnable runnable = new Runnable() {
        @Override
        public void run() {
            Log.d(TAG, "Thread id = " + Thread.currentThread().getId());
        }
    };

運行結(jié)果

HandlerThreadActivity: Thread id = 10383
HandlerThreadActivity: Thread id = 1

使用HandlerThread

先創(chuàng)建HandlerThread實例,在onCreate()方法中

handlerThread = new HandlerThread("handlerThread");
handlerThread.start();

這樣就開啟了一個帶Looper的子線程,因為HandlerThread是繼承自Thread,它的run方法是這樣定義的

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

關(guān)于Looper原理,可以參考《Android開發(fā)藝術(shù)探索》中的消息機制,我的理解是:

  • Looper.prepare();創(chuàng)建Looper實例
  • Looper.loop();進入一個無限循環(huán)中,不斷監(jiān)聽消息隊列中是否有消息,有則把他取出來分發(fā)給handler的handlerMessage()中處理。

因為線程中需要有一個Looper,線程綁定的handler才可以發(fā)送消息到消息隊列中,那么相應(yīng)的線程才會得到處理。

然后就是利用handlerThread獲取到Looper用來創(chuàng)建Handler實例

handler = new Handler(handlerThread.getLooper());

此時這個handler即使實在主線程中創(chuàng)建,但是它與子線程的Looper關(guān)聯(lián)了,所以處理消息時候也會在子線程中處理的

btn_post_to_sub_thread.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        handler.post(runnable);
    }
});

運行結(jié)果:

HandlerThreadActivity: Thread id = 10382
HandlerThreadActivity: Thread id = 10382
HandlerThreadActivity: Thread id = 10382

可以知道是在子線程中處理的。

HandlerThread和Thread的區(qū)別

  • 普通Thread主要用于在run()方法中執(zhí)行一個耗時的任務(wù)
  • HandlerThread內(nèi)部創(chuàng)建消息隊列,需要handler消息方式來通知HandlerThread去執(zhí)行一個具體的任務(wù)。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容