HandlerThread是Android开发中经常用到的类,是一个带looper的thread,用户可以很方便的通过handler通知HandlerThread进行耗时的工作。
一、典型使用场景
我们经常像下面这样使用:
HandlerThread handlerThread = new HandlerThread("testThread");
handlerThread.start();
Looper looper = handlerThread.getLooper();
// MyHandler是自定义的Handler子类
MyHandler myHandler = new MyHandler(looper);
使用HandlerThread
的Looper
创建Handler
,这样,MyHandler
的handleMessage
方法会在handlerThread
中执行,达到耗时操作在子线程中处理的目的。
二、构造函数
HandlerThread
继承自Thread
类
public class HandlerThread extends Thread
有两个构造函数,第一个设置线程优先级为默认优先级,第二个可以按照需要设定。
public HandlerThread(String name) {
super(name);
mPriority = Process.THREAD_PRIORITY_DEFAULT;
}
public HandlerThread(String name, int priority) {
super(name);
mPriority = priority;
}
三、主要代码部分
HandlerThread
的start
方法调用后,执行了下面的代码。
@Override
public void run() {
mTid = Process.myTid();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
它的主要工作是创建了Looper
,
mLooper = Looper.myLooper();
调用了onLooperPrepared
做一些用户希望的初始化工作,用户通过重载该接口实现。
/**
* Call back method that can be explicitly overridden if needed to execute some
* setup before Looper loops.
*/
protected void onLooperPrepared() {
}
我们注意到,run
方法中使用了synchronized
进行同步,
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
再看下getLooper()
方法就明白了
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
方法是异步执行的,getLooper
方法调用的时候,looper
可能还没有创建好。只要mLooper == null
,就会一直wait,直到被唤醒后发现mLooper!=null
,然后返回Looper
。
最后Looper.loop()
进行消息循环,线程阻塞,接受消息,处理消息。
四、HandlerThread结束
结束的代码很简单,就是退出消息循环,结束线程执行。
public boolean quit() {
Looper looper = getLooper();
if (looper != null) {
looper.quit();
return true;
}
return false;
}
public boolean quitSafely() {
Looper looper = getLooper();
if (looper != null) {
looper.quitSafely();
return true;
}
return false;
}