一. HandlerThread 源码分析
HandlerThread 有三个成员变量:
int mPriority; //线程的优先级,默认为:Process.THREAD_PRIORITY_DEFAULT
int mTid = -1; //线程的标记
Looper mLooper; //线程的Looper
mLooper 在 run() 方法中调用 Looper.prepare() 方法进行初始化,如下:
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
看到这里,不禁对以下这段代码产生疑问:
// 为什么要同步
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll(); //为什么要通知?通知谁?
}
继续看代码,其getLooper()方法如下:
/**
* This method returns the Looper associated with this thread. If this thread not been started
* or for any reason is isAlive() returns false, this method will return null. If this thread
* has been started, this method will block until the looper has been initialized.
* @return The looper.
*/
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;
}
由代码实现和注释可知,如果线程已经创建,但是mLooper尚未初始化,此时若调用了getLooper(),就会执行wait()方法进行阻塞,直到Looper初始化完毕,然后通过notifyAll()来唤醒线程,返回初始化后的mLooper
关于wait()方法,有如下解释:
关于wait()方法,有如下解释:
- wait()方法是从Object类继承的方法;
- 当一个线程执行到wait()方法时,它会进入到一个和该对象相关的等待池中,同时释放了对象的机锁(如果是wait(long timeout),则超时时间到后会返还对象锁);
- wait()之后使用notify()或notifyAlll()方法,或是通过设定休眠时间来唤醒当前等待池中的线程;
- wiat()必须包括在synchronized block中,否则会在程序运行时抛出”java.lang.IllegalMonitorStateException“异常。
二. 使用方法:
使用上可关联一个Handler,例子如下:
使用上可关联一个Handler,例子如下:
private HandlerThread mHandlerThread;
private Handler mHandler;
private void initHandlerThread() {
mHandlerThread = new HandlerThread("handlerthread-test");
mHandlerThread.start();
mHandler = new Handler(mHandlerThread.getLooper()) {
@Override
public void handleMessage(Message msg) {
// do sth
}
};
}
private void postMessage() {
// mHandler post message
}
@Override
protected void onDestroy() {
super.onDestroy();
// release
mHandlerThread.quit();
/**
* or use this on API level >= 18
* mHandlerThread.quitSafely();
*/
}
最后,需要注意的是在Activity退出的时候调用quit()或quitSafely()来释放资源