Tip | Android的消息机制

作者: 凌川江雪 | 来源:发表于2019-04-10 04:31 被阅读4次

    底层要点简述

    • 首先,底层实现了一个线程本地存储,叫ThreadLocal区域,
      一个主线程以及它对应的所有子线程,共享同一个 ThreadLocal对象,
      这个ThreadLocal对象中可以说逻辑上维护着一个key-value表
      这个表为不同的线程一 一 对应地维护一套数据副本
      每一套数据副本对应着一个线程
      (有多少线程共享这个ThreadLocal对象,ThreadLocal对象就准备多少套数据副本),
      每一套数据副本也是ThreadLocal对象中这个逻辑key-value表的一个项
      数据副本在这里可以具体化为Looper对象
    • 而主线程及其所有子线程都可以开辟自己的Looper
      每一个Looper都要绑定在一个Handler上,(如下方图1图2)
      然后这些个每个Looper都是共享的ThreadLocal中逻辑表的一个项,
      这个项有keyvalue两部分,
      value是每一个线程对应的Looper
      而key则是存放在ThreadLocal中一个唯一的静态的Looper对象了,(如下方图3)
      然后这个唯一的静态的Looper对象了关联着一个MessageQueue

    • 也就是说,所有线程的Looper都映射到同一个Looper上,
      所有线程的Looper中关联的MessageQueue也是映射到对应的同一个MessageQueue上;(如下方图1图2)

    整个消息机制的工作流程常规表述

    • 首先在需要传递消息的地方,我们构造一个Message(消息)对象,
      此时Message中会有自己的一个ID
      然后我们把需要传递的数据设置在这个Message里面,
      借助HandlersendMessage() 方法将Message传递到MessageQueue中,
      此时MessageQueue通过调用MessageQueue.enqueueMessage()MessageQueue自身中添加这条发送过来的Message

    • MessageQueue(消息队列)中存放着诸多相关联的Handler发送过来的Message
      其内部通过单链表的数据结构来维护消息列表,
      等待Looper的抽取。

    • Looper(消息泵)通过Looper.loop()不断轮询MessageQueue
      调用MessageQueue.next(),从MessageQueue中抽取队头的Message
      接着调用这个Message对应的HandlerdispatchMessage()
      将该Message传递分发给对应的Handler

    • 目标Handler收到Message后调用handlerMessage()处理这个消息。

    图0

    附图

    图1

    Thread(线程):负责调度整个消息循环,即消息循环的执行场所。
    存在关系:

    • 一个Thread只能有一个Looper,可以有多个Handler;
    • Looper有一个MessageQueue,可以处理来自多个Handler的Message;
    • MessageQueue有一组待处理的Message,这些Message可来自不同的Handler;
    • Message中记录了负责发送和处理消息的Handler;
    • Handler中有Looper和MessageQueue;
    图2
    图3

    参考资料:

    相关文章

      网友评论

        本文标题:Tip | Android的消息机制

        本文链接:https://www.haomeiwen.com/subject/xxhgiqtx.html