Handler源代码解析-有关Handler那些事
Handler被成为异步处理大师。相信大家都会用,面试中也常常会问到Handler的底层原理。今天就来看一看Handler的机制。
Android的消息处理有四个核心类:Handler、Looper、Message、MessageQueue,都在android.os包中。
Looper的字面意思是“循环器”,"轮询器"。它被设计用来使一个普通线程变成Looper线程。所谓Looper线程就是循环工作的线程。
在程序开发中(尤其是GUI开发中)。常常会须要一个线程不断循环,一旦有新任务则运行。运行完继续等待下一个任务,这就是Looper线程。
什么是handler?handler扮演了往MQ上加入消息和处理消息的角色(仅仅处理由自己发出的消息)。即通知MQ它要运行一个任务(sendMessage)。并在loop到自己的时候运行该任务(handleMessage),整个过程是异步的。
handler创建时会关联一个looper,默认的构造方法将关联当前线程的looper。
来看看Handler的官方凝视:
一个Handler能够让你用来发送和处理消息(Message)。以及消息上附带的Runnable对象。整个是跟消息队列(MessageQueue)一起使用的。每个Handler实例会关联到一个唯一的线程和该线程的MessageQueue。假设你创建了一个Handler,他将会跟创建这个Handler的线程和该线程的消息队列绑定在一起。也就是说通过把消息发往这个队列和在出列的时候处理他们。Handler一般有两种应用产景。(1)就是调度消息和runnable对象在未来的某个时间点运行(归纳起来就是消息的发送)。(2)能够把消息发送到其它线程里面。再简单概括一下就是Handler是跟创建他的线程绑定在一起的,然后通过消息队列方式,实现线程安全的操作。
Handler的创建
当我们调用send(),post()方法时。事实上是运行了这个:
第一句把msg.target设置为当前的handler本身。这一步非常重要,由于在这之后,就跟handler没关系了。后面会分析;接着就调用消息队列的入列方法把消息体丢到队列里面排队等待运行。
能够看到,无论是什么方式,终于都是把消息(runnable最后也是包装成消息)丢到消息队列里面。
接着是Looper的工作机制
这事实上就是一个生产者消费者的模型。在for循环里面,looper不断的订阅消息队列的下一个元素(next()方法)。然后调用Handler的dispatchMessage方式分发消息给handler进行处理。这里消息一个一个处理完之后才会处理下一个,是单线程串行运行的,并且跟创建handler的线程是同一个线程,所以完美的避免的线程安全的问题。那么你的疑问会是,到底是谁来调用这个loop方法的。不是会卡住吗?是的,这就是精髓所在,这里的looper是UI线程在初始化全然部的UI操作之后调用的,这样一来,就不会有卡住的问题了。
这里是消息分发的操作:
handleMessage方法是优先级最低的,由于有Handler有个post方法。參数是一个Runnable对象,然后通过创建一个Message,再把message的callback设置为这个runnable。然后再发送到消息队列里面。post方法的场景是你更新UI的时候须要知道获取到了什么新的数据。然后直接更新。而handleMessage方法能够不须要知道更新了哪些数据,就只更新UI就能够了。
handler之所以能够更新UI,不是系统做了什么奇妙般的兼容。而是由于他跟UI线程使用的本来就是同一个线程,UI线程通过Looper.loop来等待消息的分发,handler发送消息后把消息放到消息队列里面。而Looper负责从消息队列里面拿数据,又交给handler进行处理,终于实现了UI的异步更新操作。
这是个生产者消费者模型典型应用。当中消息队列的功劳巨大,我们来看看他有哪些功能。假设我们开发中也须要实现这样的类似的生产者消费者模型。能够使用这一套机制。
须要注意的是,MessageQueue我们不能单独定义来使用,由于其核心API的可訪问修饰符都是包级别的。我们不能把代码定义到android.os这个包以下。所以他要通过配合Looper来使用。Looper的核心API都是开放的。
enqueueMessage入列,能够把消息放到队列里面。这里队列的底层是android的本地代码实现的。事实上能够參照juc里面的DelayQueue的实现,机制差点儿相同,都支持延时出列的,这只是实现方式不同罢了。
next()出列,消息出列,队列的出列优先级是入列的时候定义的时间来决定的,时间值越小(长整形)优先级越高。
Handler源代码解析-有关Handler那些事的更多相关文章
- 深入源代码解析Android中的Handler,Message,MessageQueue,Looper
本文主要是对Handler和消息循环的实现原理进行源代码分析.假设不熟悉Handler能够參见博文< Android中Handler的使用>,里面对Android为何以引入Handler机 ...
- Android之Handler源代码深入解析
闲着没事.就来看看源代码,看看源代码的各种原理,会用仅仅是简单的,知道为什么才是最牛逼的. Handler源代码分析那,从使用的步骤来边用边分析: 1.创建一个Handler对象:new Handle ...
- Handler Looper 解析
文章讲述Looper/MessageQueue/Handler/HandlerThread相关的技能和使用方法. 什么是Looper?Looper有什么作用? Looper是用于给线程(Thread) ...
- FrameWork内核解析之Handler消息机制(二)
阿里P7Android高级架构进阶视频(内含Handler视频讲解)免费学习请点击:https://space.bilibili.com/474380680 一.Handler 在Android开发的 ...
- Android EventBus源代码解析 带你深入理解EventBus
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/40920453,本文出自:[张鸿洋的博客] 上一篇带大家初步了解了EventBus ...
- Android源代码解析之(四)-->HandlerThread
转载请标明出处:一片枫叶的专栏 上一篇文章中我们解说了AsyncTast的基本使用以及实现原理,我们知道AsyncTask内部是通过线程池和Handler实现的.通过对线程池和handler的封装实现 ...
- Android xUtils3源代码解析之网络模块
本文已授权微信公众号<非著名程序猿>原创首发,转载请务必注明出处. xUtils3源代码解析系列 一. Android xUtils3源代码解析之网络模块 二. Android xUtil ...
- Android源代码解析之(三)-->异步任务AsyncTask
转载请标明出处:一片枫叶的专栏 上一篇文章中我们解说了android中的异步消息机制. 主要解说了Handler对象的使用方式.消息的发送流程等.android的异步消息机制是android中多任务处 ...
- Android源代码解析之(十三)-->apk安装流程
转载请标明出处:一片枫叶的专栏 上一篇文章中给大家分析了一下android系统启动之后调用PackageManagerService服务并解析系统特定文件夹.解析apk文件并安装的过程,这个安装过程实 ...
随机推荐
- 十一. 图形、图像与多媒体5.Graphics2D类的绘图方法
Java语言在Graphics类提供绘制各种基本的几何图形的基础上,扩展Graphics类提供一个Graphics2D类,它拥用更强大的二维图形处理能力,提供.坐标转换.颜色管理以及文字布局等更精确的 ...
- JavaScript之String类型
这里先总结一下RegExp类型的两个主要方法: (1)exec():主要用于捕获组.接受一个参数,这个参数是主要应用模式的字符串,然后返回包含第一个匹配项信息的数组. (2)test():主要用于目标 ...
- nodejs + express访问静态资源
想访问一个资源的时候,发现访问不了 方法1.加上了这个就可以访问了,static参数为静态文件存放目录:__dirname代表目录 app.use(express.static(__dirname)) ...
- [Android Pro] java.lang.IllegalStateException: Fragment(XXFragment) not attached to Activity异常
转载:http://blog.csdn.net/winson_jason/article/details/20357435 下边两个问题,是在开发中碰到的一些关于Fragment的偶发性的问题,今天时 ...
- 二.Consumer、Producer简单例子
1.先导入jar包,我使用的是maven <dependency> <groupId>com.alibaba.rocketmq</groupId> <arti ...
- Windows 7下Maven3.0.3的安装
1.去Maven官网下载zip的maven3.0.3压缩包 2.将安装包解压到某目录,我在这里解压到D:\Program Files (x86)\apache-maven-3.0.3 3.设置系统变量 ...
- java发送http的get和post请求
import java.io.*; import java.net.URL; import java.util.Map; import java.net.HttpURLConnection;; pub ...
- python staticmethod,classmethod方法的使用和区别以及property装饰器的作用
class Kls(object): def __init__(self, data): self.data = data def printd(self): print(self.data) @st ...
- 解决ping 127.0.0.1不通的问题
用树莓派放在家里当pt下载器,一直挺惬意的,因为没有公网ip用vps和frp配置代理,偶尔ssh上去看看,一段时间也用得好好的. 可是最近这几天,在办公室ssh上去死活连不上. 于是回去后开始折腾,局 ...
- fc游戏反编译流程
最近打算玩一下nes游戏,重拾一下6502汇编. 摸索了几天,觉得下面这个反汇编的流程比较好: 用 fceux 载入游戏,选择debug菜单Code/Data Logger,点击Start,稍微玩一下 ...