1、HandlerThread 是什么?
它繼承至 Thread,具備線程的特性。它是一個帶有 Looper 的線程,并且該Looper可以被用于創(chuàng)建對應的Handler。
2、HandlerThread的作用是什么?
當一個線程執(zhí)行完一個耗時任務之后,如果想要再執(zhí)行另外一個耗時任務那么就需要重新創(chuàng)建一個新的線程,而多次進行線程的開啟和銷毀的是需要很大的開銷。在一般情況下,線程被開啟之后,也就是run方法會被執(zhí)行,若需要動態(tài)地在執(zhí)行過程做一些其它處理,例如根據(jù)不同的條件執(zhí)行不同的代碼塊,顯然是比較麻煩的。而HandlerThread解決了這個問題,它內(nèi)部維護了一個Looper不斷地去輪訓消息隊列,當需要在子線程做其他操作時,只需要通過綁定的Handler去發(fā)送消息,然后處理即可。
3、HandlerThread的工作原理
HandlerThread 是一個內(nèi)部維護一個 Looper 對象的線程。這樣就省去了創(chuàng)建線程時需要手動的創(chuàng)建 Looper 的麻煩。而已它內(nèi)部使用了
wait() 和 notifyAll() 保證的 Looper 的非空性控制。
3.1、HandlerThread#run()
- 該方法是一個loop()的死循環(huán),等待消息的到來。
- Looper.prepare()創(chuàng)建Looer對象并保存到ThreadLocal中。
- Looper.myLooper()獲取通過preparen()保存的Looper對象。
- loop()開啟輪訓器輪訓。
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
//在這里的 Looper 已經(jīng)創(chuàng)建完畢,通知 getLooper 不需要等待啦。
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();//空的回調(diào),交由用戶做一些loop()前的準備工作。
Looper.loop();
mTid = -1;
}
3.2、HandlerThread#getLooper()
獲取關聯(lián)的Looper對象,可用于外部創(chuàng)建Handler的構(gòu)造參數(shù),該方法中有一個wait()方法,然后在run()中一個notifyAll()方法,他們的作用就是在getLooper時為了保證能正確的獲取到當looper對象,當looper為null,就讓其等待,直到run()方法創(chuàng)建了其Looper對象之后調(diào)用notifyAll喚醒。
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;
}
3.3、移除消息隊列中的消息
//立即退出
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;
}
4、 IntentService 內(nèi)部 HandlerThread 的應用
@Override
public void onCreate() {
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
//開啟線程
thread.start();
//getLooper 是一個阻塞方法。
mServiceLooper = thread.getLooper();
//Handler 綁定一個通過 HandlerThread 創(chuàng)建的 looper 對象。
mServiceHandler = new ServiceHandler(mServiceLooper);
}