在非UI线程使用Handler
进行线程通信时,一般都需要进行3个步骤:
- 创建Looper
Looper.prepar()
- 创建
Handler
- 启动消息循环
Looper.loop()
通过这3步,基本就建立好了Android的多线程消息通信机制:
- Handler
- MessageQueue
- Looper
- Message
这几者可谓是你中有我,我中有你的存在......
但是,能够实现这样的机制是因为有一个重要的东西存在:ThreadLocal
.彻底理解ThreadLocal
Looper中存在一个静态的常量sThreadLocal
就是供各个线程独享的。
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
Looper.prepar()
在这里面主要执行了2步:
-
构建一个looper
- 构建一个looper的messageQueue成员
mQueue = new MessageQueue()
- 将当前线程存入looper的mThread成员中
mThread = Thread.currentThread()
- 将looper存入sThreadLocal中
- 构建一个looper的messageQueue成员
private static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper(quitAllowed));
}
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
创建Handler
创建Handler时主要进行了将Handler与Looper绑定的操作:
- 通过
Looper.myLooper()
类方法获取当前线程的threadLocal中储存的looper,将这个looper绑定到handler的成员变量mLooper中mLooper = Looper.myLooper()
- 将mLooper中的messageQueue绑定到handler的成员变量mQueue中
mQueue = mLooper.mQueue()
mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;
Looper.loop()
- 声明一个局部常量
final Loop me = myLoop()
-
myLoop()
将返回当前线程的looper成员
-
- 声明一个局部常量
final MessageQueue queue
- 将me.mQueue赋值给queue
- 进入无限循环
//进入无限循环 for (;;) { //取出一条消息 Message msg = queue.next(); //没有消息就阻塞 if (msg == null) { return; } ... //分发消息 try { msg.target.dispatchMessage(msg); //msg.target是一个Handler对象 } finally { if (traceTag != 0) { Trace.traceEnd(traceTag); } } ... //回收消息 msg.recycleUnchecked();
如有问题,欢迎指出_