handler在安卓开发中是必须掌握的技术,但是很多人都是停留在使用阶段。使用起来很简单,就两个步骤,在主线程重写handler的handleMessage( )方法,在工作线程发送消息。但是,有没有人想过这种技术是怎么实现的呢?下面我们一起探讨下。

先上图,让大家好理解下handler机制:


handler机制示例图

上面一共出现了几种类,ActivityThread,Handler,MessageQueue,Looper,msg(Message),对这些类作简要介绍:

ActivityThread:程序的启动入口,为什么要介绍这个类,是因为该类就是我们说的主线程,它对Looper进行操作的。

Handler:字面意思是操控者,该类有比较重要的地方,就是通过handler来发送消息(sendMessage)到MessageQueue和 操作控件的更新(handleMessage)。handler下面持有这MessageQueue和Looper的对象。

MessageQueue:字面意思是消息队列,就是封装Message类。对Message进行插入和取出操作。

Message:这个类是封装消息体并被发送到MessageQueue中的,给类是通过链表实现的,其好处方便MessageQueue的插入和取出操作。还有一些字段是(int what,Object obj,int arg1,int arg2)。what是用户定义的消息和代码,以便接收者(handler)知道这个是关于什么的。obj是用来传输任意对象的,arg1和arg2是用来传递一些简单的整数类型的。

下面,我们按照启动顺序来进行源码分析:

从上面可以看出,ActivityThread类是用来启动Android的,其源码为:


ActivityThread类:

接下来,我们看到Looper类了,我们进去看看里面的源码实现:

首先,我们看看里面有哪些字段:

 Looper的内部属性

然后我们迫不及待地要想去看看prepareMainLooper方法,到底干了什么

Looper.prepareMainLooper()方法

这里我们可以看到,prepareMainLooper是为了设置一个持有消息队列和消息序列器的Looper进去ThreadLocal。接下来我们看看loop方法吧:

Looper.loop()方法

我们可以看到loop方法中,会取出内部的消息序列器,并且迭代里面的消息,根据消息的target分发消息(到handleMessage方法中)。如果你有疑问,你应该是不清楚Looper的MessageQueue为什么会有Message。那么我们就马上去看,到底是哪里添加消息的。话说,到了这里我也好像没有分析到和我们handler相关的操作吧。因为你和我都知道handler的作用是sendMessage和handleMessage,所以我们知道,Looper中的消息序列器的消息体,肯定是从sendMessage中添加进去的。不墨迹,我们马上进入Handler的源码分析。

首先,我们先看看Handler的字段:

Handler的字段

接着,我们看看Handler的构造方法,我们可以看到,Handler有两类构造方法(别看到6个,它们都是往这两种方法调用的):

Handler的构造方法

接着,我们要进入Handler.dispatchMessage()方法,因为我们要解释上面刚刚Looper.loop方法。dispatchMessage的方法很简单,只有三个方向,其源码为:

Handler.dispatchMessage()方法

到这里为止,执行代码就结束了。那么问题来了,消息从哪里来的?带着这个疑问,我们马上进入Handler.sendMessage()逻辑去看看,其源码是:

Handler.sendMessage()方法

好不容易找到了发送消息的逻辑并理解了,但是还要去壳,在MessageQueue中分析了,首先,我们回顾下,消息序列器是在Looper.prepare()中初始化的。MessageQueue源码,构造方法很简单:

MessageQueue构造方法

然后我们再到达MessageQueue.enqueueMessage()方法中看源码:

MessageQueue.enqueueMessage()方法

这个是发送消息的最终执行代码,就是把消息放进消息序列器。在Looper.loop()方法中,我们是需要不断从消息序列器中取出消息的。其过程也是我们可以进去MessageQueue.next()的源码中看看:

MessageQueue.next()方法

这样,整个过程就完成了。在这些执行过程中,Message是它们的物件。我们可以看看Message的结构:

Message的字段

除此之外,Message的数据结构是基于链表的,方法都很简单的,我就不贴出来了。

总结一下,其实就是用一个ThreadLocal来存储对象,然后在执行的时候,能够保证对象的不变形,这样就能达到在主先线程更新UI了。

【转载】Android 的 Handler 机制实现原理分析的更多相关文章

  1. [转]Android中handler机制的原理

    Andriod提供了Handler 和 Looper 来满足线程间的通信.Handler先进先出原则.Looper类用来管理特定线程内对象之间的消息交换(MessageExchange). 1)Loo ...

  2. Handler系列之原理分析

    上一节我们讲解了Handler的基本使用方法,也是平时大家用到的最多的使用方式.那么本节让我们来学习一下Handler的工作原理吧!!! 我们知道Android中我们只能在ui线程(主线程)更新ui信 ...

  3. Android 为什么要有handler机制?handler机制的原理

    为什么要有handler机制? 在Android的UI开发中,我们经常会使用Handler来控制主UI程序的界面变化.有关Handler的作用,我们总结为:与其他线程协同工作,接收其他线程的消息并通过 ...

  4. Redis数据持久化机制AOF原理分析一---转

    http://blog.csdn.net/acceptedxukai/article/details/18136903 http://blog.csdn.net/acceptedxukai/artic ...

  5. Android的Handler机制

    Handler机制的原理 Android 的 Handler 机制(也有人叫消息机制)目的是为了跨线程通信,也就是多线程通信.之所以需 要跨线程通信是因为在 Android 中主线程通常只负责 UI ...

  6. 为什么要有handler机制?handler机制的原理

    为什么要有handler机制? 在Android的UI开发中,我们经常会使用Handler来控制主UI程序的界面变化.有关Handler的作用,我们总结为:与其他线程协同工作,接收其他线程的消息并通过 ...

  7. Android事件分发机制源码分析

    Android事件分发机制源码分析 Android事件分发机制源码分析 Part1事件来源以及传递顺序 Activity分发事件源码 PhoneWindow分发事件源码 小结 Part2ViewGro ...

  8. Android 异步通信:图文详解Handler机制工作原理

    前言 在Android开发的多线程应用场景中,Handler机制十分常用 今天,我将图文详解 Handler机制 的工作原理,希望你们会喜欢 目录 1. 定义 一套 Android 消息传递机制 2. ...

  9. Android中线程间通信原理分析:Looper,MessageQueue,Handler

    自问自答的两个问题 在我们去讨论Handler,Looper,MessageQueue的关系之前,我们需要先问两个问题: 1.这一套东西搞出来是为了解决什么问题呢? 2.如果让我们来解决这个问题该怎么 ...

随机推荐

  1. [Spring cloud 一步步实现广告系统] 1. 业务架构分析

    什么是广告系统? 主要包含: 广告主投放广告的<广告投放系统> 媒体方(广告展示媒介-)检索广告用的<广告检索系统> 广告计费系统(按次,曝光量等等) 报表系统 Etc. 使用 ...

  2. Java从入门到精通系统书籍,吐血整理的,只要1元

    思诚为修身之本,而明善又为思诚之本 我会在支付宝联系你 付完款后在支付宝账单详情页 点击联系收款方.我会回复您下载链接.

  3. Vue结合后台导入导出Excel问题详解

    话不多说,直接上前端代码 axios({ method: 'post', url: 'http://localhost:19090/exportUser',//这个是请求的地址 params: {// ...

  4. windows 应急流程及实战演练

    前言 本文摘自信安之路公众号的文章. 当企业发生黑客入侵.系统崩溃或其它影响业务正常运行的安全事件时,急需第一时间进行处理,使企业的网络信息系统在最短时间内恢复正常工作,进一步查找入侵来源,还原入侵事 ...

  5. QT总结

    作为一个QT(C++/linux/windows)开发工程师,把自己在工作中遇到的一些QT问题持续总结给大家,一起分享: 一.隐藏鼠标:QApplication::setOverrideCursor( ...

  6. 微信小程序如何做金额输入限制

    引言:金额输入时,需求如下: 1)首位不能出现0或者小数点(.) 2)仅保留两位小数 3)仅保留一个小数点(.),不允许出现多个. 1.wxml核心代码: <!-- 1.adjust-posit ...

  7. HTML Rendering Error

    刚下载的markdown弹窗提示html渲染错误 去官网   http://markdownpad.com/faq.html#livepreview-directx  页面搜索 This view h ...

  8. linux下关闭selinux

    找到 /etc/sysconfig/selinux 文件 修改 SELINUX=enable 使之 SELINUX=disable 重启 reboot

  9. eNSP仿真软件之VLAN基础配置及Access接口

    ★Access接口是交换机上用来连接用户主机的接口. 实验内容: 实验步骤: (1)      打开仿真软件eNSP,新建拓扑.根据实验内容建立如下实验拓扑图. (2)      按照如下的编址表对每 ...

  10. ASM与ASMD

    时序机 状态机 控制器 数据通路之间的关系 样例代码