今天我們來(lái)看一個(gè)簡(jiǎn)單的 HandlerThread胖替,前面我們學(xué)習(xí)過(guò)了 handle 故痊,現(xiàn)在再來(lái)看 HandlerThread 會(huì)發(fā)現(xiàn)真是簡(jiǎn)單的不得了
HandlerThread 簡(jiǎn)單的說(shuō)就是 在一個(gè) Thread 里面封裝了一個(gè) looper ,然后啟動(dòng)該 looper 看靠,外接和這個(gè) HandlerThread 的交互都是通過(guò) handle 發(fā)送消息赶促,因?yàn)?HandlerThread 可以返回其虐不的 looper 對(duì)象,然后我們用這個(gè) looper 對(duì)象創(chuàng)建 handle 對(duì)象發(fā)送消息
HandlerThread 的用法
// 創(chuàng)建 HandlerThread 對(duì)象并啟動(dòng) HandlerThread 所屬線程挟炬,構(gòu)造方法需要傳線程的名字進(jìn)去
HandlerThread handlerThread = new HandlerThread("AAAAAAAA");
handlerThread.start();
// 通過(guò) HandlerThread 對(duì)象內(nèi)部的 looper 構(gòu)建用于通訊的 handle
Handler otherHandle = new Handler(handlerThread.getLooper()) {
@Override
public void handleMessage(Message msg) {
if (msg.what == 1) {
Log.d("AAA", Thread.currentThread().getName() + "接受消息" + System.currentTimeMillis());
}
}
};
// 執(zhí)行線程間通訊任務(wù)
otherHandle.sendMessage(Message.obtain());
// 不需要了就關(guān)閉線程鸥滨,
handlerThread.quit();
// handlerThread.quitSafely();
大家要是吧前面我說(shuō) handle 的那篇搞明白,這 HandlerThread 的使用實(shí)在不是要太簡(jiǎn)單了
看看源碼吧
其實(shí)猜都能猜到的谤祖,這是 HandlerThread 聲明的成員變量
public class HandlerThread extends Thread {
int mPriority;
int mTid = -1;
Looper mLooper;
private @Nullable Handler mHandler;
{
這是核心 run 方法
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
在線程啟動(dòng)時(shí)把 looper 消息隊(duì)列跑起來(lái)
有意思的地方來(lái)了
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 {
// 會(huì)阻塞
wait();
} catch (InterruptedException e) {
}
}
}
return mLooper;
}
大家注意 getLooper() 方法是給別的線程調(diào)用的婿滓,因?yàn)?handle 的構(gòu)造方法不能接受 null 的 looper 對(duì)象,要不會(huì)拋異常粥喜,所以這里在其他線程獲取 HandlerThread 的 looper 對(duì)象時(shí)空幻,若是發(fā)現(xiàn)此時(shí) looper 對(duì)象是 null 的,那么就會(huì)阻塞調(diào)用 getLooper() 方法的外部線程容客。
直到 run 的初始化同步代碼段跑完秕铛,此時(shí) looper 初始化完成,會(huì)主動(dòng)喚醒所有阻礙在 looper 對(duì)象身上的 線程缩挑,我們?cè)賮?lái)看看 HandlerThread 的run 方法
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
// 主動(dòng)喚醒所有阻礙在 looper 對(duì)象身上的 線程
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
好了但两,HandlerThread 很簡(jiǎn)單的,這里就基本完事了供置。我們看 HandlerThread 源碼一定要理解 HandlerThread 為啥要 wait谨湘,什么時(shí)候 notifyAll 。這個(gè)是 HandlerThread 里面最值得學(xué)習(xí)的點(diǎn)芥丧,學(xué)會(huì)了很有用的紧阔。