什么是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
说明它本质上还是一个Thread
,只不过前面加了一个定语Handler
。可以猜测这个Thread里包含了一个Handler
,有Handler
肯定还少不了Looper
。
在Android中,主线程会自动启动一个Looper
去不断的处理消息,启动的代码在 ActivityThread
的 main
方法中代码如下:
public static void main(String[] args) {
...
Looper.prepareMainLooper();
...
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
Looper.loop();
...
}
这样系统处理一些消息就可以通过Handler
发送消息到Looper
的消息队列。如果我们也想有这样的一个消息处理系统怎么办呢,答案就是用HandlerThread
呀
先来看一下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;
}
可以看到首先调用了 Looper.prepare()
,然后调用了 Looper.loop()
和主线程启动类似。在Looper.loop()
方法中执行了一个for
循环,不断从消息队列(MessageQueue)中取出消息处理。
quit()
public boolean quit() {
Looper looper = getLooper();
if (looper != null) {
looper.quit();
return true;
}
return false;
}
quitSafely()
public boolean quitSafely() {
Looper looper = getLooper();
if (looper != null) {
looper.quitSafely();
return true;
}
return false;
}
有两个quit方法,这两个quit方法有什么区别呢?直接看下代码(Looper.java
)
public void quit() {
mQueue.quit(false);
}
public void quitSafely() {
mQueue.quit(true);
}
最终调用的都是mQueue.quit
方法
void quit(boolean safe) {
if (!mQuitAllowed) {
throw new IllegalStateException("Main thread not allowed to quit.");
}
synchronized (this) {
if (mQuitting) {
return;
}
mQuitting = true;
if (safe) {
removeAllFutureMessagesLocked();
} else {
removeAllMessagesLocked();
}
// We can assume mPtr != 0 because mQuitting was previously false.
nativeWake(mPtr);
}
}
可以看到,当直接退出的时候,会把消息队列中所有的消息都取消掉。如果是安全退出,会把延时的消息取消掉,非延时的消息会处理完。有点类似线程池ExecutorService
的 shutdown()
和 shutdownNow()
方法。
Looper 的 quitSafely 方法从 api level 18才可以使用
扫描二维码关注公众号,回复: 3886017 查看本文章
优点
HandlerThread
相比于Thread
一次创建线程,就可以不断的处理消息,减少了频繁创建线程带来的资源消耗。
使用场景
满足以下两个场景即可使用HandlerThread
- 需要子线程处理任务
- 要处理多个任务
使用
一个小demo
https://github.com/77Y/HandlerThread