HandlerThread本质上还是Thread,继承了Thread。它与Thread的区别是内部维护了一个Looper。当我们在子线程中使用Handler的时候需要创建一个Looper
public void run() {
super.run();
Looper.prepare();
Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
//...
}
};
Looper.loop();
}
这样写需要我们自己创建一个Looper,当有了HandlerThread的时候我们就不必这个做了,采用HandlerThread的代码如下
HandlerThread handlerThread = new HandlerThread("thread name");
handlerThread.start();
mHandler = new Handler(handlerThread.getLooper())
HandlerThead的源码比较简单,这里就直接贴出来了
/**
* 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.
*
*/
public class HandlerThread extends Thread {
int mPriority;
int mTid = -1;
Looper mLooper;
private @Nullable Handler mHandler;
// name是线程名
public HandlerThread(String name) {
super(name);
mPriority = Process.THREAD_PRIORITY_DEFAULT;
}
// priority是线程优先级
public HandlerThread(String name, int priority) {
super(name);
mPriority = priority;
}
// 当Looper 准备好的时候调用
protected void onLooperPrepared() {
}
//代码的核心,创建Looper,并调用loop开启消息队列的循环
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();//如果有调用getLooper的去通知Looper已经准备好了,可以返回给调用者了。
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
// 获得线程的Looper
public Looper getLooper() {
if (!isAlive()) {
return null;
}
// 如果线程开启了,会一直等到Looper创建完成,再返回创建的Looper
// 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;
}
// 获得与该Looper关联的Handler,隐藏方法
@NonNull
public Handler getThreadHandler() {
if (mHandler == null) {
mHandler = new Handler(getLooper());
}
return mHandler;
}
// 退出线程的Looper
public boolean quit() {
Looper looper = getLooper();
if (looper != null) {
looper.quit();
return true;
}
return false;
}
// 安全的退出线程的Looper
public boolean quitSafely() {
Looper looper = getLooper();
if (looper != null) {
looper.quitSafely();
return true;
}
return false;
}
//获得线程id,通过Process.myTid()获得的
public int getThreadId() {
return mTid;
}
}
quit和quieSafely的区别
quit方法把MessageQueue消息池中所有的消息全部清空。quitSafely方法只会清空MessageQueue消息池中所有的延迟消息(延迟消息是指通过sendMessageDelayed或postDelayed等方法发送的消息),非延迟消息则不清除继续派发出去让Handler去处理