HandlerThread的源码分析
介绍
HandlerThread是Thread的子类,它是一种可以使用Handler的Thread。普通的Thread是为了执行耗时的任务的,而HanderThread内部创建了消息队列,外界需要通过Handler的消息方式通知HanlerThread来执行一个具体的任务。
源码分析
HandlerThread中的字段:
1 | int mPriority; |
mPriority,设置线程的优先级;
mTid,线程的唯一标示;
mLooper,HandlerThread中Looper。
构造方法:
1 | public HandlerThread(String name) { |
1 | public HandlerThread(String name, int priority) { |
HandlerThread继承了Thread类,并重写了其run方法:1
2
3
4
5
6
7
8
9
10
11
12
13@Override
public void run() {
mTid = Process.myTid();//当前线程的标示,和线程设置优先级有关,这里貌似没用到。
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();//获取当前线程的Looper
notifyAll();//通知所有等待获取Looper的线程停止等待
}
Process.setThreadPriority(mPriority);//设置线程的优先级
onLooperPrepared();//在开启循环之前,做一些初始化的操作
Looper.loop();
mTid = -1;
}
1 | protected void onLooperPrepared() { |
run方法中调用了 Looper.prepare()方法为当前的HandlerThread创建了Looper,同时调用Looper.loop方法开启了消息循环。
getLooper()方法:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16public 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;
}
得到当前HandlerThread的Looper。
quit方法:1
2
3
4
5
6
7
8public boolean quit() {
Looper looper = getLooper();
if (looper != null) {
looper.quit();
return true;
}
return false;
}
调用了Looper的quit方法,终止Looper内部的循环,这个方法会立即终止,即使还有未处理的消息。
quitSafely:1
2
3
4
5
6
7
8public boolean quitSafely() {
Looper looper = getLooper();
if (looper != null) {
looper.quitSafely();
return true;
}
return false;
}
调用了Looper的quitSafely方法,终止Looper内部的循环,这个方法会等Looper内部的消息队列中所有的消息处理完毕后才终止Looper内部的循环。
getThreadId方法:1
2
3public int getThreadId() {
return mTid;
}
得到当前HandlerThread的mTid(线程的唯一标示)。
使用注意
从源码可以看出,HandlerThread的run方法中调用了Looper.loop()方法,而loop方法是一个无限循环的方法,所以run方法也是一个无限循环的方法,因此当我们确定不再使用HandlerThread的时候,最好调用HandlerThread的quit活着quitSafely方法来终止HandlerThread,避免资源浪费。
Android中的IntentService内部使用到了HandlerThread,关于HanlerThread的使用可以参考:IntentService源码分析