對HandlerThread的理解

提示:閱讀本文之前可先閱讀Android個人筆記之Android的消息機制

HandlerThread本質上就是一個普通Thread,只不過內部建立了Looper.看下源碼

public class HandlerThread extends Thread {
    int mPriority;
    int mTid = -1;
    Looper mLooper;

    public HandlerThread(String name) {
        super(name);
        mPriority = Process.THREAD_PRIORITY_DEFAULT;
    }
    

    public HandlerThread(String name, int priority) {
        super(name);
        mPriority = priority;
    }
    

    protected void onLooperPrepared() {
    }

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

    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;
    }

    
    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;
    }

    /**
     * Returns the identifier of this thread. See Process.myTid().
     */
    public int getThreadId() {
        return mTid;
    }
}

由此看出HandlerThread除了有個優(yōu)先級之外,與自己手動創(chuàng)建Looper的Thread并沒有什么不同。這里有一個地方要理解一下,也許你已經發(fā)現了
run方法里面當mLooper創(chuàng)建完成后有個notifyAll(),getLooper()中有個wait(),這是為什么呢?因為mLooper在HandlerThread中執(zhí)行,而我們的handler是在UI線程初始化的,也就是說,我們必須等到mLooper創(chuàng)建完成,才能正確的返回getLooper();wait(),notify()就是為了解決這兩個線程的同步問題。

既然系統(tǒng)給我們提供了這么一個類,到底有什么好處呢?

HandlerThread的常規(guī)用法

  • 啟動線程,構造參數:String代表線程名,priority代表優(yōu)先級。優(yōu)先級范圍為-20到19,默認為0,優(yōu)先級越高,獲得的CPU資源更多,反之則越少。-20代表優(yōu)先級最高,反之19最低。
mThread = new HandlerThread("handler_thread"); 
mThread.start();
  • 創(chuàng)建處理任務的mWorkHandler和更新UI的mUIHandler。
mWorkHandler = new Handler(mThread.getLooper());
mUIHandler = new Handler();
  • mWorkHandler與HandlerThread的Looper關聯,并在handleMessage(Message msg)中處理任務,處理完之后通知mUIHandler對UI進行刷新。
  • 在合適的時機退出HandlerThread,比如activity中的onDestroy(),方法有quit()和quitSafely()

具體處理方式要看具體需求,不過總體思路跟上面三個步驟差不多。如果想處理多個任務。就發(fā)送多個消息,在mWorkHandler進行處理。

HandlerThread的特點

  • HandlerThread將loop轉到子線程中處理,說白了就是將分擔MainLooper的工作量,降低了主線程的壓力,使主界面更流暢。
  • 開啟一個線程起到多個線程的作用。處理任務是串行執(zhí)行,按消息發(fā)送順序進行處理。
    相比多次使用new Thread(){…}.start()這樣的方式節(jié)省系統(tǒng)資源。
    但是由于每一個任務都將以隊列的方式逐個被執(zhí)行到,一旦隊列中有某個任務執(zhí)行時間過長,那么就會導致后續(xù)的任務都會被延遲處理。
  • HandlerThread擁有自己的消息隊列,它不會干擾或阻塞UI線程。
  • 通過設置優(yōu)先級就可以同步工作順序的執(zhí)行,而又不影響UI的初始化;

總結

HandlerThread比較適用于單線程+異步隊列的場景,比如IO讀寫操作,耗時不多而且也不會產生較大的阻塞。對于網絡IO操作,HandlerThread并不適合,因為它只有一個線程,還得排隊一個一個等著。

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

相關閱讀更多精彩內容

友情鏈接更多精彩內容