HandlerThread是一套安全的使用Handler機(jī)制的線程,在Thread中創(chuàng)建Handler并且使用Handler和線程通信也是一種任務(wù)調(diào)度場(chǎng)景票灰,而在Thread中創(chuàng)建Handler需要考慮到線程安全以及同步的問(wèn)題摸恍。
1.線程start之后饶碘,并不會(huì)立刻進(jìn)入run方法中,也就是說(shuō)在線程中使用Looper.prepare()然后再start線程撩独,并不能夠立刻就創(chuàng)建Looper對(duì)象比伏,此時(shí)直接去獲取Looper是null胜卤。
2.線程的同步問(wèn)題,Looper對(duì)象在創(chuàng)建的時(shí)候需要做好同步赁项,否則在多個(gè)線程創(chuàng)建的時(shí)候會(huì)導(dǎo)致Looper重復(fù)創(chuàng)建葛躏,進(jìn)而使app崩潰。
HandlerThread很好的處理好了這2個(gè)問(wèn)題悠菜,首先對(duì)于第一個(gè)問(wèn)題舰攒,在線程start之后,我們使用getLooper()獲取Looper的時(shí)候悔醋,當(dāng)Looper對(duì)象還沒(méi)創(chuàng)建摩窃,就會(huì)使線程進(jìn)入等待狀態(tài),直到Looper對(duì)象創(chuàng)建完成并且返回芬骄。
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;
}
在run方法中HandlerThread在創(chuàng)建Looper對(duì)象的時(shí)候也做好了同步猾愿。
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
同時(shí)開(kāi)放出onLooperPrepared()方法給子類(lèi)繼承擴(kuò)展,類(lèi)似于Activity中的onCreate方法账阻。
另外Handler還提供了退出HandlerThread的方法蒂秘。
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;
}