Skip to content
Able Blog
Home
Others
  • Home
      • 学习笔记
          • Android
            • 简历_赵思琦_Android_5年经验
                • Handler
                  • 01. handler整体架构方案原理
                    • 02. Message源码分析
                      • 03. Looper源码分析
                        • 04. ThreadLocal的使用及源码解析文章
                          • 05. MessageQueue源码解析
                            • 06. Handler源码解析
                              • 07. 源码阅读总结
                                • 08. Carson Handler总结的机制源码解析
                                  • 消息的处理
                                    • 一.Handler是如何绑定当前线程的?
                                      • 2. 绑定MessageQueue
                                      • 总结
                                        • 二.MessageQueue是如何将消息出队的
                                          • 三.Handler.dispatchMessage
                                            • 1. Handler.handleCallback()
                                              • 2. Handler.handleMessage
                                              • 消息的发送
                                                • 1. 使用Message.target.dispatchMessage() 中target,Message是什么时候持有Handler引用的
                                                  • 2. enqueueMessage 消息入队
                                                  • post
                                                  • 09. handler 内存泄漏的原因

                                              08. Carson Handler总结的机制源码解析

                                              author iconAblecalendar icon2022年4月16日category icon
                                              • Android
                                              tag icon
                                              • Handler
                                              • 学习笔记
                                              word icon约 559 字

                                              此页内容
                                              • 消息的处理
                                                • 一.Handler是如何绑定当前线程的?
                                                • 2. 绑定MessageQueue
                                              • 总结
                                              • 二.MessageQueue是如何将消息出队的
                                              • 三.Handler.dispatchMessage
                                                • 1. Handler.handleCallback()
                                                • 2. Handler.handleMessage
                                              • 消息的发送
                                                • 1. 使用Message.target.dispatchMessage() 中target,Message是什么时候持有Handler引用的
                                                • 2. enqueueMessage 消息入队
                                              • post

                                              # 08. Carson Handler总结的机制源码解析

                                              在阅读一次源码后模糊不懂的点,解析及影响加深

                                              地址open in new window

                                              # 消息的处理

                                              # 一.Handler是如何绑定当前线程的?

                                              Handler初始化的时候,做了2件事

                                              # 1. 指定Looper对象。

                                              Looper对象的获取来自LocalThread.get(). Looper对象的创建来自于Looper.prepare(),使用ThreadLocal.set(new Looper()). 而ThreadLocal将Looper对象与当前线程绑定。

                                              # ThreadLocal

                                              ThreadLocal 实例通常是希望将状态与线程相关联的类中的私有静态字段

                                              # 2. 绑定MessageQueue

                                              Handler的MessageQueue来自Looper.mQueue。而Looper.mQueue在 Looper对象创建时初始化。

                                              # 总结

                                              Handler初始化的时候从ThreadLocal,将Looper实例与线程关联,持有Looper中的MessageQueue对象的引用。所以从子线程发送的消息,可以通过MessageQueue获取Messager到looper,并使用 msg.target.dispatchMessage(msg)分发消息。

                                              # 二.MessageQueue是如何将消息出队的

                                              按照Messager对象的创建时间顺序出队。

                                              # 三.Handler.dispatchMessage

                                              # 1. Handler.handleCallback()

                                              回调Runnable对象里复写的run()

                                              # 2. Handler.handleMessage

                                              复写子类handleMessage方法

                                              # 消息的发送

                                              # 1. 使用Message.target.dispatchMessage() 中target,Message是什么时候持有Handler引用的

                                              Handler.enqueueMessage中,将当前Handler实例作为message的target属性。

                                              # 2. enqueueMessage 消息入队

                                              消息队列里,无消息就插入队头,有消息就按照Message入队时间插入到队列中。

                                              之后随着Looper对象的无限循环消息,不断从消息队列中取出消息,分发到对应的handler

                                              boolean enqueueMessage(Message msg, long when) {
                                              
                                                              ...// 仅贴出关键代码
                                              
                                                              synchronized (this) {
                                              
                                                                  msg.markInUse();
                                                                  msg.when = when;
                                                                  Message p = mMessages;
                                                                  boolean needWake;
                                              
                                                                  // 判断消息队列里有无消息
                                                                      // a. 若无,则将当前插入的消息 作为队头 & 若此时消息队列处于等待状态,则唤醒
                                                                      if (p == null || when == 0 || when < p.when) {
                                                                          msg.next = p;
                                                                          mMessages = msg;
                                                                          needWake = mBlocked;
                                                                      } else {
                                                                          needWake = mBlocked && p.target == null && msg.isAsynchronous();
                                                                          Message prev;
                                              
                                                                      // b. 判断消息队列里有消息,则根据 消息(Message)创建的时间 插入到队列中
                                                                          for (;;) {
                                                                              prev = p;
                                                                              p = p.next;
                                                                              if (p == null || when < p.when) {
                                                                                  break;
                                                                              }
                                                                              if (needWake && p.isAsynchronous()) {
                                                                                  needWake = false;
                                                                              }
                                                                          }
                                              
                                                                          msg.next = p; 
                                                                          prev.next = msg;
                                                                      }
                                              
                                                                      if (needWake) {
                                                                          nativeWake(mPtr);
                                                                      }
                                                                  }
                                                                  return true;
                                                          }
                                              
                                              
                                              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
                                              26
                                              27
                                              28
                                              29
                                              30
                                              31
                                              32
                                              33
                                              34
                                              35
                                              36
                                              37
                                              38
                                              39
                                              40
                                              41
                                              42
                                              43
                                              44

                                              # post

                                              内部根据Runnable对象而封装。 实际上是创建Messager对象,让Messager持有callback,然后在dispatchMessage的时候调用messager.callback.run();

                                              edit icon编辑此页open in new window
                                              上次编辑于: 2022/4/17 23:10:35
                                              贡献者: zsqan
                                              上一页
                                              07. 源码阅读总结
                                              下一页
                                              09. handler 内存泄漏的原因
                                              默认页脚
                                              Copyright © 2022 Able