本文讨论Android的消息机制,基于Android7.1代码,旨在通过本文对Android的消息机制有一个基础的认识
主要分三部分进行讨论:Handler、Looper、MessageQueue
Part1:Handler部分 【frameworks/base/core/java/android/os/Handler.java】
Handler的sendMessage方法层层跟进最终调用到了sendMessageAtTime方法,如下所示


图片.png 图片.png 图片.png

这里的Queue来自于looper


图片.png

从此处代码可以看出,Handler与Looper,和MessageQueue正是在此处关联起来的


图片.png

Part2:Looper部分【frameworks/base/core/java/android/os/Looper.java】


图片.png

另外,再看下Looper的构造函数

图片.png

MessageQueue包装在了Looper对象中

由此可以看出,通过ThreadLocal使得线程和Looper关联上,因为MessageQueue包装在了Looper对象中,从而消息队列与线程关联上,并且不同的线程就不能访问对方的消息队列。
三者关系图如下

图片.png 图片.png

这里说下TLS即线程局部存储(Thread Local Storage,TLS),通过TLS机制,为每一个使用该全局变量的线程都提供一个变量值的副本,每一个线程均可以独立地改变自己的副本,而不会和其它线程的副本冲突。从线程的角度看,就好像每一个线程都完全拥有该变量。而从全局变量的角度上来看,就好像一个全局变量被克隆成了多份副本,而每一份副本都可以被一个线程独立地改变。
这里的代码就是为每个线程创建一个自己的Looper副本,而不用synchronized同步机制来处理,A线程改变了A的looper副本,不影响B线程的Looper,从而比较高效的实现线程安全。

上面代码可以看出在Looper准备好后,线程会调用Looper.loop(),进入真正的循环机制。loop()函数的代码流程非常简单,只不过是在一个for循环里不停从消息队列中摘取消息,而后调用msg.target.dispatchMessage()对消息进行派发处理而已。
这里的msg.target域比较重要,这个域记录的其实就是当初向消息队列发送消息的那个handler。

Part3:MessageQueue部分【frameworks/base/core/java/android/os/MessageQueue.java】
Handler的sendMessageAtTime()时,最终会调用queue.enqueueMessage()将消息push进消息队列
这里对消息链表里如何插入Message,以及消息队列如何感知消息变化的,这里不多加介绍,牵涉到管道和epoll机制。可以自行阅读MessageQueue.java的enqueueMessage方法追下去

这里顺便说下我们平时定义Handler的较好做法


图片.png

小结:
通过Handler向Looper的消息队列中插入Message,而后再由Looper在消息循环里具体处理。因为消息队列本身不具有链表一变动就能马上感知的功能,所以它需要借助管道和epoll机制来监听变动。当外界向消息队列中打入新消息后,就向管道的“写入端”写入简单数据,于是epoll可以立即感知到管道的变动,从何激发从消息队列中摘取消息的动作。这就是Android消息机制的大体情况。

本文参考文章
https://my.oschina.net/youranhongcha/blog/492591
http://www.jb51.net/article/81932.htm

更多相关文章

  1. Android(安卓)面试准备
  2. Android菜鸟的成长笔记(17)—— 再看Android中的Unbounded Service
  3. Android(安卓)最佳实践
  4. Android主线程里不允许网络操作
  5. android Can't create handler inside thread that has not call
  6. android通过webservice验证用户
  7. UML详解:解析Android消息处理机制:Handler/Thread/Looper & Messag
  8. 【Android(安卓)okhttp源码解析 二】同步请求流程和源码分析
  9. Android正确关闭线程

随机推荐

  1. 实用技术经验分享:《Android账户同步备份
  2. Android学习札记52:广播(Broadcast)基础篇
  3. 4.1 Android如何访问资源
  4. android进程和线程模型
  5. Android笔记:Android后台接口教程一(从零开
  6. Android(安卓)插件化 动态升级
  7. 两份安卓学习资料,我建议你看完
  8. android之NDK(jni)开发笔记1——运行第一个
  9. Android高手进阶教程(二十五)之---Androi
  10. android实现ios形式的字体,实现各种自定义