相信不是刻意去了解的話,很多同學對HandlerThread、Thread、Handler都有點傻傻分布清楚。
本文幫你區別并了解三者的基本用法。
首先,Thread,線程,這個是沒有疑問的。
Thread基本用法
Thread類實現了Runnable接口,必須重寫run()方法;
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
}
});
或者
class myThread implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
}
}
啟動一個線程,用start()方法;
HandlerThread基本用法
我喜歡看源碼注釋,因此慣例地,貼上開篇的方法注釋:
Handy class for starting a new thread that has a looper.
The looper can then be used to create handler classes.
Note that start() must still be called.
翻譯過來就是:
使用HandlerThread可以方便的開啟一個線程,并且這個線程已經綁定了一個looper了。這個looper可以用來new一個handler類。注意在此之前,要調用start()方法。
示例代碼如下:
HandlerThread thread1 = new HandlerThread("test1");
thread1.start();
那么我們不禁要問了,為什么這個線程已經綁定了一個Looper了呢?還要在此之前調用start()方法?
答案就是:提前調用start()方法就是為了為線程綁定Looper的。
我們知道,start()方法可以開啟一個線程,調用線程的run()方法。而HandlerThread的run()方法是這樣的:
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
看到沒,run()方法里面調用Looper.prepare()來為線程綁定一個Looper。 Looper.loop()開啟消息循環。相當于把原來的需要調用Looper.prepare()、Looper.loop()做了一下封裝。
有了Looper之后,我們就可以創建Handler,就可以在這個線程里面發送消息、處理消息了。
HandlerThread和Handler結合使用
我們知道,Handler在使用時,需要一個Looper(以及Looper的消息隊列MessageQueue),這樣它才能發送消息,處理消息。
根據Handler創建方法的不同,我們可以這樣用:
HandlerThread thread1 = new HandlerThread("test1");
thread1.start();
Handler mHandler = new Handler(thread1.getLooper()); // Handler創建方法1
// 或者: Handler創建方法2
Handler mHandler = new Handler(thread1.getLooper(), new Callback() {
@Override
public boolean handleMessage(Message msg) {
// TODO Auto-generated method stub
return false;
}
});
}
// 或者 Handler創建方法3
Handler.Callback callback = new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
// TODO Auto-generated method stub
return false;
}
};
Handler mHandler = new Handler(thread1.getLooper(), callback);
// Handler創建方法4,重寫HandleMessage方法
static class TestHandler extends Handler {
public TestHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
}
}
HandlerThread 終止消息循環的方法
使用完HandlerThread時,不要忘了退出消息循環。
HandlerThread終止消息循環有兩種方法,quit()和quitSafely(),調用的是Looper的對用方法,而Looper調用的是MessageQueue的對應方法。
quitSafely()源碼:
public boolean quitSafely() {
Looper looper = getLooper();
if (looper != null) {
looper.quitSafely();
return true;
}
return false;
}
發現HandlerThread的quitSafely()其實是調用了Looper的quitSafely()方法:
public void quitSafely() {
mQueue.quit(true);
}
同樣,HandlerThread的quit()則是調用了Looper的quit()方法:
public void quit() {
mQueue.quit(false);
}
Looper終止消息循環具體可參考:
http://www.lxweimin.com/p/767de5b99962
參考:
HandlerThread源碼:
http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.1.1_r1/android/os/HandlerThread.java#HandlerThread
MessageQueue源代碼:
http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.1.1_r1/android/os/MessageQueue.java#MessageQueue.quit%28boolean%29
http://blog.sina.com.cn/s/blog_5da93c8f0101kio1.html
[Android HandlerThread 完全解析]
(http://blog.csdn.net/lmj623565791/article/details/47079737)