在非UI线程使用Handler
进行线程通信时,一般都需要进行3个步骤:
- 创建Looper
Looper.prepar()
- 创建
Handler
- 启动消息循环
Looper.loop()
通过这3步,基本就建立好了 Android 的多线程消息通信机制:
- Handler
- MessageQueue
- Looper
- Message
这几者可谓是你中有我,我中有你的存在。通过 Handler 发送 Message 到 Looper 的 MessageQueue 中,待 Looper 的循环执行到 Message 后,就会根据 Message 的 target handler,回调对应 Handler 的 handlerMessage 方法。
例如: Thread-A 拥有一个 Looper,Thread-B 持有一个在 Thread-A 中构造的 Handler,Thread-B 就可以通过这个 Handler 将 Message 发送到 Thread-A 的 Looper 的 MessageQueue 中,然后消息会走到 Thread-A 的 Handler 的 handleMessage 方法。
Looper 原理图
在 Looper 类加载时就会创建一个 ThreadLocal 类型的类变量 sThreadLocal
|
|
Looper.prepar()
|
|
在这里面主要执行了 3 步:
- 构建一个 looper
- 构建一个 messageQueue 成员
- 将当前线程存入 mThread 中
- 将构造的 looper 存到类变量 sThreadLocal 中
至此,执行 Looper.praper 的当前线程就会拥有一个 looper 成员了,存放在 Looper 的 sThreadLocal 中。
创建Handler
|
|
|
|
Looper.loop()
-
声明一个局部常量
final Loop me = myLoop()
myLoop()
将返回当前线程的looper成员
-
声明一个局部常量
final MessageQueue queue
- 将me.mQueue赋值给queue
-
进入无限循环
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
//进入无限循环 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();
-
通过
Message.obtain()
获取的消息,需要使用Handler.sendMessage()
插入到消息队列。 -
通过
Handler.obtainMessage()
获取的消息,可以使用message.sendToTaget()
插入到消息队列。