之前已经了解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 = -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; }
以上代码是HandlerThread主要的代码,我们可以看见run方法中构建了Looper的消息循环,并没有Handler,可以说HandlerThread就是一个加了消息循环的Thread,在这里看起来和Handler并没有什么关系。
我们在使用的时候才会把Handler和HandlerThread的Looper绑定在一起,构建成一个完整的消息传递系统。