之前已经了解Handler的一些知识,今天主要研究Google封装的实现线程通信的一个类HandlerThread。
一、HandlerThread使用
@Override
protected void onCreate(Bundle savedInstanceState) {
......
HandlerThread handlerThread = new HandlerThread("handler-thread");
handlerThread.start(); mHandler = new Handler(handlerThread.getLooper()){
@Override
public void handleMessage(Message msg) {
//这里已经不是在主线程,而是在HandlerThread线程中了
super.handleMessage(msg);
}
};
//主线程向子线程发送消息
mHandler.sendEmptyMessage(100);
}
- new一个HandlerThread并启动
- 实例化Handler并获取HandlerThread的Looper
- 可以在任何地方使用handler发送消息,handler里面实现是异步的
HandlerThread简单的替代了之前研究过的一段代码,如下:
Thread mThread = new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare();
mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
......
super.handleMessage(msg);
}
};
Looper.loop();
}
});
这样替代后我们不用自己去实现Thread,来执行耗时操作。
HandlerThread本身是一个Thread,在里面做了一个消息循环的管道,Handler往里面扔消息,并得到消息进行处理。
对比上面两个mHandler,我们可以发现其构造方法不一样,一个没有传Looper,通过Handler源码可以发现是使用当前线程的Looper,一个有,用的就是HandlerThread的Looper。
public Handler(Looper looper, Callback callback, boolean async) {
mLooper = looper;
mQueue = looper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
上述只是Handler其中一个构造方法,传Looper的类会最终走到这个构造方法中,有两个参数需要注意1、mLooper 2、mQueue
Handler在构建的时候就拿到Looper和MessageQueue,传输消息机制就是很容易理解了。
没有传Looper的构造方法只是把mLooper = looper 换成了mLooper = Looper.myLooper()。
二、源码分析
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -;
} 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;
}
以上代码是HandlerThread主要的代码,我们可以看见run方法中构建了Looper的消息循环,并没有Handler,可以说HandlerThread就是一个加了消息循环的Thread,在这里看起来和Handler并没有什么关系。
我们在使用的时候才会把Handler和HandlerThread的Looper绑定在一起,构建成一个完整的消息传递系统。