概述:
为了 线程间 通信方便, Handler 机制 通过 Handler 和 Looper, MessageQueue, Message 这些 类 之间的协作, 简化 多线程的开发. 线程的交互 会被封装 到 Message 中, 然后 通过 Handler 的方法 把 消息 放到 MessageQueue 消息队列中, 实现 Handler 机制的线程 都会 调用 Looper 的 loop() 方法, 则 Looper 作为 消息分发者的 作用就体现出来了. loop() 方法中, 会 从消息队列 MessageQueue 中 获取 Message, 然后 将 获取到的Message 丢给 负责 处理消息的 Handler . Handler 再 根据 Message 中的 callback(Runnable) 是否为 空 以及 Handler 中的 回调 mCallback(Handler.Callback) 是否为空 来决定 最终交给 哪个 方法进行消息处理.
-----------------------------------------------------------------------------------------------------------------------
Handler 机制中, 各个角色的分工如下:
1. Handler : 负责消息(Message) 的发送 和 处理
2. Looper : 负责 消息的 分发
3. MessageQueue : 负责消息的 管理
4. Message : 带有 int 型参数 what 以及 arg1 和 arg2,这些是为了 简化 通过 setData(Bundle bundle) 设置的 数据, 以及 一个 任意 对象的 参数 obj. 如果期望的 话 还 可以 带一个 Runnable 类型的参数 callback,
--------------------------------------------------------------------------------------------------------------------
第一部分: Handler
Handler 的创建 :
1. 如果 参数 有 Looper 则 把 Looper 赋值给 mLooper 否则 则 把 当前 线程 对应的 Looper 赋值给 mLooper. 2. 获取 Looper 对应的 消息 队列 mQueue. 3. 如果 构造函数的参数中 包含 Handler.Callback 的 实例 callBack 则 把其 赋值给 mCallback 变量.
Handler 消息的发送:
1. 要 发送的消息 内容 有 两种 一种 Runnable 另一种 Message.
通过 跟踪 post 的实现, 则 可以发现 Runnable 也 被 转化 为 Message 对象了.
图1:图2:
2. 消息发送 调用的 常见方法有 : post(Runnable), postDelayed(Runnable,long), 以及 sendEmptyMessage(int), sendMessage(Message) , sendMessageDelayed(Message,long) 这些方法都会 归宗于 : sendMessageAtTime()
在 sendMessageAtTime 中 主要 是把 Message 对应的 target 参数 设置为 当前 Handler, 然后 把 此 msg 放入 MessageQueue 队列中,
3. 消息 处理时 对应的方法回调:
handle 消息 处理的位置 有 三处:其1: 当 消息为 Runnable 消息的时候, 则 msg 的 callback (即 Runnable 对象) 是不为 空的, 则 直接 调用 msg.callback.run() 执行 回调.其2: 当我们在 构造 Handler 的时候 有 传入 Handler.Callback 回调对象的时候, 则 mCallback 不为空( 由 Handler 的构造函数 可知), 则 调用 Handler.Callback 这个 接口 对应的 handleMessage() 方法.其3: 如果 没有前面 两种, 则 在 创建 Handler 的 子类 或者 匿名对象的时候 会 重载 handleMessage 来 处理对应的 回调逻辑.
第二部分: Looper
looper 的初始化:
当 调用 Looper 的静态 方法 prepare() 的时候则 会创建 一个 Looper 对象, 并设置 到一个 静态的县城局部变量中去.在 Looper 的构造函数中, 可以看到 会创建 一个 MessageQueue 对象, MessageQueue 作为 消息队列.
Looper.loop() 方法的调用
一个线程 调用 prepare() 只是 准备好了消息队列, 进入 消息队列的 等待, 则是 调用 Looper 的 loop() 方法:透过 loop() 方法的实现, 可以知道 首先从 当前 线程对应的 Looper 中 获取到 对应的消息 队列, 然后 从 消息 队列中 获取 下一条 要执行 的 message, 当 获取到的 Message 为 null 的时候则 直接退出循环.如果 msg 不为null, 则 调用 Message 中 对应的 Handler 对象的 dispatchMessage 方法 进行消息的分发. 消息的具体分发 已在上面 讲过了.在 queue.next() 语句的 上面 可以 看到 for 循环 是一个 死 循环, 则 可以知道 当 线程 调用 loop() 方法之后 就不会 继续往 下执行, 而 是在 等待 消息列表(queue) 返回消息 , 然后 将 消息 丢给 Handler 进行处理.