知道Handler,那你知道HandlerThread嗎?

ClericYi發表於2020-02-21

知道Handler,那你知道HandlerThread嗎?

前言

知識儲備:手撕Handler

面試題庫:泓洋大神等人的Github專案

雖然HandlerThread其實在我的專案中並沒有使用到過,而我現在也是準備面試的一個階段,學的多也總是沒有壞處。

思維導圖

知道Handler,那你知道HandlerThread嗎?

基礎用法

// 建立Handler例項
HandlerThread handlerThread  = new HandlerThread("MainActivity");
// 執行緒啟動
handlerThread.start();
// 基於HandlerThread構建的Looper
Handler handler = new Handler(handlerThread.getLooper()){
            @Override
            public void handleMessage(@NonNull Message msg) {
                super.handleMessage(msg);
                Log.e(TAG, msg.what+"");
            }
        };
// 使用handler傳送訊息
handler.sendEmptyMessage(1);
// 退出Lopper的死迴圈
handlerThread.quit();
複製程式碼

揭祕HandlerThread

先看看HandlerThread的家庭裡有哪些成員呢?

// 一個繼承自Thread的類
public class HandlerThread extends Thread {
    int mPriority; // 優先順序
    int mTid = -1;
    Looper mLooper; // Looper
    private @Nullable Handler mHandler; // Handler
}
複製程式碼

主要的已經標示出解釋,因為在之前的手撕Handler已經比較全面的講解過了Handler以及Looper的作用,這裡我們應該也能比較清晰的知道HandlerThread的組成成分應該是Handler+Thread

之前在手撕Handler的講解中,Looper指的是在ActivityThread中定義的,也就是一個全域性型的Looper,並且他的初始化是如下所示的。

Handler handler = new Handler(new Handler.Callback() {
            @Override
            public boolean handleMessage(@NonNull Message msg) {
                return false;
            }
        });
複製程式碼

而這個初始化函式最後呼叫的Looper也就是我們指的一個全域性的Looper。 下面給出這個建構函式呼叫的程式碼。

public Handler(@Nullable Callback callback, boolean async) {
        if (FIND_POTENTIAL_LEAKS) {
            final Class<? extends Handler> klass = getClass();
            if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
                    (klass.getModifiers() & Modifier.STATIC) == 0) {
                Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
                    klass.getCanonicalName());
            }
        }

        mLooper = Looper.myLooper(); // 獲得ActivityThread中初始化的Looper
        if (mLooper == null) {
            throw new RuntimeException(
                "Can't create handler inside thread " + Thread.currentThread()
                        + " that has not called Looper.prepare()");
        }
        mQueue = mLooper.mQueue;
        mCallback = callback;
        mAsynchronous = async;
    }
複製程式碼

這就是HandlerThread中的Handler和上述定義的Handler的區別了,但是他們的工作原理是一致的,只是變化了Looper

使用HandlerThread的優缺點

使用場景:單執行緒+非同步任務場景

優點:

  1. 將loop執行在子執行緒中處理,減輕了主執行緒的壓力,使主執行緒更流暢
  2. 序列執行,開啟一個執行緒起到多個執行緒的作用
  3. 有自己的訊息佇列,不會干擾UI執行緒

缺點:

  1. 由於每一個任務佇列逐步執行,一旦佇列耗時過長,訊息延時
  2. 對於IO等操作,執行緒等待,不能併發

以上就是我的學習成果,如果有什麼我沒有思考到的地方或是文章記憶體在錯誤,歡迎與我分享。


相關文章推薦:

手撕OkHttp

手撕AsyncTask

多執行緒程式設計基礎(一)-- 執行緒的使用

手撕Handler

相關文章