用了许久的Handler,对于Handler的使用确实是比较熟悉,但是具体内部是如何运作的,却只是模糊的。Handler发出的消息怎么到达MessageQueue?MessageQueue的数据怎么被轮循处理?Looper是怎么循环取MessageQueue的消息的。今天,通过在子线程中创建Looper的实例,以追溯源码的方式来分析这个流程,通过这种方式来理解Android的消息处理机制。

首先,如果我们想在子线程里边实现这个Handler消息处理机制,我们这样处理:

这么简单的几行代码,就能完成一个消息机制,背后肯定是封装了不少的逻辑,还是得学习一下Google大神的编程思路,能把代码简化到这种程度。下面我们跟着代码,一步步展开这个代码的运作过程。

首先,调用Looper的静态方法prepare(),并且将Looper传入ThreadLocal,后边用到。

由此可看到,在此创建了该线程的Looper对象,Looper对象创建时,会创建出MessageQueue!(后边会使用该MessageQueue来轮循及Handler会消Message发送至此)!

紧接着,便是创建Handler,此处使用了刚刚Looper所创建的MessageQueue(可见,handler的创建要后于Looper),这里便完成了MessegeQueue的连通!

顺带地,我们看看handler发送消息时做了些什么。此处调用了enqueueMessage,将消息放入刚刚从Looper获取到的MessageQueue。

继续就是调用了Looper.loop(),通过myLooper获取到Looper.

此处,通过ThreadLocal获取得Looper,前边调用prepare时传入ThreadLocal!

继续查看loop方法!由此可看见一个死循环,这就是Looper能够循环取消息的道理!(当然,子线程也会因为此处不断循环而阻塞于此,暂不运行线程loop以下的方法,直到Looper被调用退出!)

此处loop将从messageQueue取出的消息中Handler,并且调用其dispatchMessage

此时会接着调用应用所实现的handleMessage方法,处理相关的逻辑!

子类必须实现的handleMessage方法!

自此,完成了整个流程的分析,以前看着很绕,现在看看源码,感觉还是蛮清晰的。

小结:Looper创建了消息队列,然后把消息队列传给相应的handler(Looper先于Handler创建),从而实现两者的沟通,然后,looper再不断地从消息队列里取数据,当应用调用该线程的handler,并且发送消息,Looper从队列取出,然后再回调用户实现的handlerMessage方法。因此,线程消息的处理机制,在Android方面,最本质的是Looper,所以创建的handler传入什么线程的Looper,则该handler的数据也同时运行了该线程之下。此时就很好理解,getMainLooper的作用了。

加油,共勉!

通过源码简要分析之Android消息机制Handler、Looper、MessageQueue运行机制相关推荐

  1. Android中的Handler, Looper, MessageQueue和Thread

    前几天,和同事探讨了一下Android中的消息机制,探究了消息的发送和接收过程以及与线程之间的关系.虽然我们经常使用这些基础的东西,但对于其内部原理的了解,能使我们更加容易.合理地架构系统,并避免一些 ...

  2. 通过源码分析Android 的消息处理机制

    2019独角兽企业重金招聘Python工程师标准>>> #通过源码分析Android 的消息处理机制 我们知道,Android应用是通过消息来驱动的,每一个进程被fork之后,都会在 ...

  3. RxJava Agera 从源码简要分析基本调用流程(2)

    2019独角兽企业重金招聘Python工程师标准>>> 版权声明:本文由晋中望原创文章,转载请注明出处:  文章原文链接:https://www.qcloud.com/communi ...

  4. 【Kafka】Kafka如何通过源码实现监控

    1.概述 问题导读: 1.kafka的消费者组的消费偏移存储,kafka支持两个版本? 2.ConsumerOffsetChecker类的作用是什么? 3.Kafka如何通过源码实现监控? 一,基本思 ...

  5. Nginx实战基础篇六 通过源码包编译安装部署LNMP搭建Discuz论坛

    Nginx实战基础篇六 通过源码包编译安装部署LNMP搭建Discuz论坛 版权声明: 本文遵循"署名非商业性使用相同方式共享 2.5 中国大陆"协议 您可以自由复制.发行.展览. ...

  6. 本周两场直播丨通过源码了解openGauss多线程架构;Oracle数据库索引分裂详解。...

    1.管中窥豹之通过源码了解openGauss多线程架构-8月18日20:00 本讲座主要介绍openGauss的多线程架构,通过源码了解线程间通信机制.线程池的原理和优势.如何开启线程池等,力图通过多 ...

  7. NoSQLRedis的介绍和Redis安装部署,通过yum在线安装Redis,通过源码安装Redis;

    目录 1.Redis简介 1).Redis是什么? 2).Redis能干嘛? 3).可以从哪里去下载Redis? 4).使用Redis进行的多种操作 5).Redis与其他数据库和软件的对比 2.Re ...

  8. [Java] HashMap 源码简要分析

    特性 * 允许null作为key/value. * 不保证按照插入的顺序输出.使用hash构造的映射一般来讲是无序的. * 非线程安全. * 内部原理与Hashtable类似. 源码简要分析 publ ...

  9. Linux下通过源码编译安装程序

    本文简单的记录了下,在Linux下如何通过源码安装程序,以及相关的知识. 一.程序的组成部分 Linux下程序大都是由以下几部分组成: 二进制文件:也就是可以运行的程序文件 库文件:就是通常我们见到的 ...

最新文章

  1. ASP .NET 如何在 SQL 查询层面实现分页
  2. 栈和队列都是限制存取点的线性结构_栈的练习以及解析
  3. “知识图谱+”系列:知识图谱+图神经网络
  4. 算法图解:如何找出栈中的最小值?
  5. 屏幕强大!一加7 Pro海外版发布:2K分辨率 90Hz刷新率
  6. 数据结构专题(二):2.5在链表指定位置插入元素
  7. 21天学通java 3_《21天学通Java》PDF 下载
  8. 《Linux命令行与shell脚本编程大全 第3版》Linux命令行---41
  9. 一次网站登录慢故障排查
  10. 安装包及教程:仿真工具Multisim12.0 简体中文汉化版 安装包及详细安装教程(含安装包和汉化包百度云盘链接)
  11. 【信号检测】基于matlab双稳随机共振微弱信号检测【含Matlab源码 1701期】
  12. Office2010激活失败 错误码2503、2502解决方案
  13. 题目内容: 班级第一次列队,通常老师会让同学按身高排成一列,然后1、2报数,喊到1的同学向前一 步,就这样,队伍就变成两列了。假设现在一个班级有n个同学,并且他们已经按身高排成 了一列,同学按身高从1
  14. b站React禹哥版视频笔记-React应用(基于react脚手架)
  15. 山东大学计算机科学与技术专业全国排名,全国计算机专业大学排名
  16. ViewPager+Fragment添加一行若干小红球滚动指示器指示当前ViewPager翻阅位置(可供第三方使用的类)
  17. Vue中qs插件的使用
  18. Bidirectional A*
  19. 安装Nvidia驱动run文件
  20. 量化分析师的Python日记【Q Quant兵器谱 -之偏微分方程1】

热门文章

  1. 根据印刷行业的特点,整理出MES管理系统解决方案
  2. sel2000服务器自动关闭,管家婆辉煌:轻松处理SQL 2000数据库自动停止
  3. FFmpeg源码分析:swr_convert()音频格式转换
  4. Gee引擎配置微端后登录游戏黑屏怎么办?
  5. 微博html5到桌面,HTML 分享页面到QQ/微信、微博等平台
  6. 证件照制作:使用PS打印一寸照片
  7. Springboot+MySQL实现多数据源的信息导入
  8. 【阿里云】1.阿里云大数据产品体系
  9. 台式电脑键盘错乱会出现计算机模式怎么办,键盘错乱怎么修复错位(台式电脑键盘按键错乱)...
  10. 电信增值短信平台软件模块清单(sp专用)