简单应用场景
在子线程向主线程发送消息, 一般刷新主线程的 UI
主线程向子线程发送消息, 一般为启动异步阻塞任务
- class MessageMechanismActivity : AppCompatActivity() {
- companion object {
- private const val TAG = "MessageMechanism"
- private const val MSG_UPDATE_START = 1
- private const val MSG_UPDATE_OVER = 2
- }
- private var mainHandler: Handler? = null
- private var threadHandler: Handler? = null
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_message_mechanism)
- // thread1 -> main thread
- mainHandler = TestHandler() // main thread 中
- this.btn_handler_in_main.setOnClickListener{
- mainHandler!!.sendEmptyMessage(MSG_UPDATE_START)
- // thread1
- object : Thread() {
- override fun run() {
- Thread.sleep(2000)
- // thread1->threadMain
- mainHandler!!.sendEmptyMessage(MSG_UPDATE_OVER)
- }
- }.start()
- }
- // main thread -> thread2
- // thread2
- object : Thread() {
- override fun run() {
- Looper.prepare()
- threadHandler = TestHandler() // 在此线程中创建 Handler
- Looper.loop()// may block
- }
- }.start()
- this.btn_handler_in_other_thread.setOnClickListener {
- // threadMain -> thread2
- threadHandler!!.sendEmptyMessage(MSG_UPDATE_START)
- }
- }
- class TestHandler : Handler() {
- init {
- Log.d(TAG, "init:${Thread.currentThread().name}")
- }
- override fun handleMessage(msg: Message?) {
- Log.d(TAG, "thread:${Thread.currentThread().name}")
- super.handleMessage(msg)
- when(msg?.what){
- MSG_UPDATE_START -> {
- val sdf = SimpleDateFormat("HH:mm:ss", Locale.CHINA)
- Log.d(TAG, "开始更新:${sdf.format(Date())}")
- }
- MSG_UPDATE_OVER -> {
- val sdf = SimpleDateFormat("HH:mm:ss", Locale.CHINA)
- Log.d(TAG, "完成更新:${sdf.format(Date())}")
- }
- }
- }
- }
- }
类说明
Thread
成员 ThreadLocal.ThreadLocalMap. 用于存储各种 ThreadLocal 数据
ThreadLocal
一个对象能在多个线程中保存各自的数据, 保存或获取数据时会调用当前线程的 ThreadLocal.ThreadLocalMap 进行处理
Looper
成员 MessageQueue
成员 Thread. 创建 Looper 的当前线程
成员 ThreadLocal<Looper>, 用于在当前线程存储当前 Looper
- MessageQueue
- Handler
成员 Looper. 当前线程的 Looper
成员 MessageQueue.Looper 中的 MessageQueue
Handler 发送消息流程
在线程 A 中, 创建 Looper,MessageQueue,Handler, 并用 Looper 维护 MessageQueue
在线程 B 中, 调用 Handler 发送消息, 添加消息到 MessageQueue;
在线程 A 中, Looper 从 MessageQueue 拿出消息交给 Handler 处理
image.png
线程 A 中, 创建 Looper 和 MessageQueue
->Looper.prepare(). 创建 Looper 和 MessageQueue, 并在当前线程的 ThreadLocalMap 中保存 Looper
- private static void prepare(boolean quitAllowed) {
- // 一个线程只能创建一个 Looper
- if (sThreadLocal.get() != null) {
- throw new RuntimeException("Only one Looper may be created per thread");
- }
- // 创建 Looper 并保存在当前线程的 ThreadLocalMap 中
- sThreadLocal.set(new Looper(quitAllowed));
- }
- private Looper(boolean quitAllowed) {
- mQueue = new MessageQueue(quitAllowed);
- mThread = Thread.currentThread();
- }
线程 A 中, 创建 Handler
- ->Handler()
- // Handler.class
- public public Handler(Callback callback, boolean async) {
- // ...
- // 获取当前线程的 Looper
- mLooper = Looper.myLooper();
- // 当前线程中没有 Looper 则不能创建
- if (mLooper == null) {
- throw new RuntimeException(
- "Can't create handler inside thread that has not called Looper.prepare()");
- }
- mQueue = mLooper.mQueue;
- // ...
- }
- // Looper.class
- public static @Nullable Looper myLooper() {
- return sThreadLocal.get();
- }
- // ThreadLocal.class
- // 从当前线程中的 ThreadLocalMap 中获取 ThreadLocal 值
- public T get() {
- Thread t = Thread.currentThread();
- ThreadLocalMap map = getMap(t);
- if (map != null) {
- ThreadLocalMap.Entry e = map.getEntry(this);
- if (e != null) {
- @SuppressWarnings("unchecked")
- T result = (T)e.value;
- return result;
- }
- }
- return setInitialValue();
- }
线程 A 中, Looper 维护 MessageQueue
- -> Looper.loop()
- // Looper.loop 核心代码
- public static void loop() {
- final Looper me = myLooper();
- final MessageQueue queue = me.mQueue;
- for (;;) {
- // might block. 因为 queue.next() 也是一个永真循环
- Message msg = queue.next();
- // msg.target 是 Handler, 一般最终会调用 Handler.handleMessage
- msg.target.dispatchMessage(msg);
- }
- }
- //MessageQueue.class 轮询取出消息
- Message next() {
- for (;;) {
- if (now <msg.when) {
- // Next message is not ready. Set a timeout to wake up when it is ready.
- nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);
- } else {
- // Got a message.
- mBlocked = false;
- if (prevMsg != null) {
- prevMsg.next = msg.next;
- } else {
- mMessages = msg.next;
- }
- msg.next = null;
- if (DEBUG) Log.v(TAG, "Returning message:" + msg);
- msg.markInUse();
- return msg;
- }
- }
- }
B 线程中, 发送消息
- ->Handler.sendMessage()->...->Handler.enqueueMessage()// 会设置 msg.target = this
- ->MessageQueue.enqueueMessage()// 添加消息到消息队列
- // MessageQueue.class 添加消息到消息队列相关代码
- boolean enqueueMessage(Message msg, long when{
- msg.when = when;
- Message p = mMessages;
- boolean needWake;
- if (p == null || when == 0 || when <p.when) {
- // 插到头部
- msg.next = p;
- mMessages = msg;
- needWake = mBlocked;
- } else {
- // 插入到队列中间
- Message prev;
- for (;;) {
- p = p.next;
- if (p == null || when < p.when) {
- // 插入规则: 或者是最后一个, 或者根据处理事件顺利插入
- break;
- }
- if (needWake && p.isAsynchronous()) {
- needWake = false;
- }
- }
- msg.next = p; // invariant: p == prev.next
- prev.next = msg;
- }
- }
A 线程中, 拿出消息并处理
- ->Looper.loop()->Handler.dispatchMessage()
- ->message.callback.run() || mCallback.handleMessage(msg) || handleMessage(msg);
- // Handler.class
- public void dispatchMessage(Message msg) {
- if (msg.callback != null) {
- handleCallback(msg);
- } else {
- if (mCallback != null) {
- if (mCallback.handleMessage(msg)) {
- return;
- }
- }
- handleMessage(msg);
- }
- }
来源: http://www.jianshu.com/p/ee502fb58b22