簡述HandlerThread原始碼
public class HandlerThread extends Thread { int mPriority; int mTid = -1; Looper mLooper; private @Nullable Handler mHandler; public HandlerThread(String name) { super(name); mPriority = Process.THREAD_PRIORITY_DEFAULT; } /** * Constructs a HandlerThread. * @param name * @param priority The priority to run the thread at. The value supplied must be from * {@link android.os.Process} and not from java.lang.Thread. */ public HandlerThread(String name, int priority) { super(name); mPriority = priority; } /** * Call back method that can be explicitly overridden if needed to execute some * setup before Looper loops. */ 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; } /** * This method returns the Looper associated with this thread. If this thread not been started * or for any reason isAlive() returns false, this method will return null. If this thread * has been started, this method will block until the looper has been initialized. * @return The looper. */ 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; } /** * @return a shared {@link Handler} associated with this thread * @hide */ @NonNull public Handler getThreadHandler() { if (mHandler == null) { mHandler = new Handler(getLooper()); } return mHandler; }
關鍵的就是這些,很明顯的可以看出,handlerThread在一個子執行緒裡面封裝好了looper和handler,所以這就是為什麼在子執行緒裡面使用handlerThread直接run就可以了。
在getLooper裡面,handlerThread對執行緒是否存在加了一個判斷,因為handler在主執行緒,而handlerThread建立的Looper在子執行緒,如果子執行緒沒有建立或者子執行緒的Looper沒有建立,那handler也不知道給誰發訊息。所以這裡handlerThread加了一層判斷,確保子執行緒的Looper建立。
關於handlerThread的使用場景,一般就是在子執行緒中使用,因為如果按照正常的handler使用的話,需要自己額外在子執行緒新建一個Looper(由於主執行緒已經預設有一個Looper了,所以在主執行緒可以直接用handler)。例如在子執行緒不斷地獲取資料更新UI的時候,就可以用到handlerThread。