提示:阅读本文之前可先阅读Android个人笔记之Android的消息机制
HandlerThread本质上就是一个普通Thread,只不过内部建立了Looper.看下源码
public class HandlerThread extends Thread {
int mPriority;
int mTid = -1;
Looper mLooper;
public HandlerThread(String name) {
super(name);
mPriority = Process.THREAD_PRIORITY_DEFAULT;
}
public HandlerThread(String name, int priority) {
super(name);
mPriority = priority;
}
protected void onLooperPrepared() {
}
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
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;
}
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;
}
/**
* Returns the identifier of this thread. See Process.myTid().
*/
public int getThreadId() {
return mTid;
}
}
由此看出HandlerThread除了有个优先级之外,与自己手动创建Looper的Thread并没有什么不同。这里有一个地方要理解一下,也许你已经发现了
run方法里面当mLooper创建完成后有个notifyAll(),getLooper()中有个wait(),这是为什么呢?因为mLooper在HandlerThread中执行,而我们的handler是在UI线程初始化的,也就是说,我们必须等到mLooper创建完成,才能正确的返回getLooper();wait(),notify()就是为了解决这两个线程的同步问题。
既然系统给我们提供了这么一个类,到底有什么好处呢?
HandlerThread的常规用法
- 启动线程,构造参数:String代表线程名,priority代表优先级。优先级范围为-20到19,默认为0,优先级越高,获得的CPU资源更多,反之则越少。-20代表优先级最高,反之19最低。
mThread = new HandlerThread("handler_thread");
mThread.start();
- 创建处理任务的mWorkHandler和更新UI的mUIHandler。
mWorkHandler = new Handler(mThread.getLooper());
mUIHandler = new Handler();
- mWorkHandler与HandlerThread的Looper关联,并在handleMessage(Message msg)中处理任务,处理完之后通知mUIHandler对UI进行刷新。
- 在合适的时机退出HandlerThread,比如activity中的onDestroy(),方法有quit()和quitSafely()
具体处理方式要看具体需求,不过总体思路跟上面三个步骤差不多。如果想处理多个任务。就发送多个消息,在mWorkHandler进行处理。
HandlerThread的特点
- HandlerThread将loop转到子线程中处理,说白了就是将分担MainLooper的工作量,降低了主线程的压力,使主界面更流畅。
- 开启一个线程起到多个线程的作用。处理任务是串行执行,按消息发送顺序进行处理。
相比多次使用new Thread(){…}.start()这样的方式节省系统资源。
但是由于每一个任务都将以队列的方式逐个被执行到,一旦队列中有某个任务执行时间过长,那么就会导致后续的任务都会被延迟处理。 - HandlerThread拥有自己的消息队列,它不会干扰或阻塞UI线程。
- 通过设置优先级就可以同步工作顺序的执行,而又不影响UI的初始化;
总结
HandlerThread比较适用于单线程+异步队列的场景,比如IO读写操作,耗时不多而且也不会产生较大的阻塞。对于网络IO操作,HandlerThread并不适合,因为它只有一个线程,还得排队一个一个等着。