相信不是刻意去了解的话,很多同学对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.jianshu.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)