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那些事的更多相关文章

  1. 深入源代码解析Android中的Handler,Message,MessageQueue,Looper

    本文主要是对Handler和消息循环的实现原理进行源代码分析.假设不熟悉Handler能够參见博文< Android中Handler的使用>,里面对Android为何以引入Handler机 ...

  2. Android之Handler源代码深入解析

    闲着没事.就来看看源代码,看看源代码的各种原理,会用仅仅是简单的,知道为什么才是最牛逼的. Handler源代码分析那,从使用的步骤来边用边分析: 1.创建一个Handler对象:new Handle ...

  3. Handler Looper 解析

    文章讲述Looper/MessageQueue/Handler/HandlerThread相关的技能和使用方法. 什么是Looper?Looper有什么作用? Looper是用于给线程(Thread) ...

  4. FrameWork内核解析之Handler消息机制(二)

    阿里P7Android高级架构进阶视频(内含Handler视频讲解)免费学习请点击:https://space.bilibili.com/474380680 一.Handler 在Android开发的 ...

  5. Android EventBus源代码解析 带你深入理解EventBus

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/40920453,本文出自:[张鸿洋的博客] 上一篇带大家初步了解了EventBus ...

  6. Android源代码解析之(四)--&gt;HandlerThread

    转载请标明出处:一片枫叶的专栏 上一篇文章中我们解说了AsyncTast的基本使用以及实现原理,我们知道AsyncTask内部是通过线程池和Handler实现的.通过对线程池和handler的封装实现 ...

  7. Android xUtils3源代码解析之网络模块

    本文已授权微信公众号<非著名程序猿>原创首发,转载请务必注明出处. xUtils3源代码解析系列 一. Android xUtils3源代码解析之网络模块 二. Android xUtil ...

  8. Android源代码解析之(三)--&gt;异步任务AsyncTask

    转载请标明出处:一片枫叶的专栏 上一篇文章中我们解说了android中的异步消息机制. 主要解说了Handler对象的使用方式.消息的发送流程等.android的异步消息机制是android中多任务处 ...

  9. Android源代码解析之(十三)--&gt;apk安装流程

    转载请标明出处:一片枫叶的专栏 上一篇文章中给大家分析了一下android系统启动之后调用PackageManagerService服务并解析系统特定文件夹.解析apk文件并安装的过程,这个安装过程实 ...

随机推荐

  1. 使用Python SocketServer快速实现多线程网络服务器

    Python SocketServer使用介绍 1.简介: SocketServer是python的一个网络服务器框架,可以减少开发人员编写网络服务器程序的工作量. SocketServer总共有4个 ...

  2. 面试通用tips--来源某猎头人员

  3. ArcGIS 10.2 三维分析工具箱部分工具不能用

    如在以下面的方式操作时发现弹出错误提示, “ Unable to execute the selected tool”... 问题解决方法为: 点击Extensions...,然后把下图中的选项全部勾 ...

  4. maven本地仓库地址的设置

    对于大公司的jenkins来说,仓库是很大的,那么存储仓库的目录空间一定要足够大才可以. 可以对linux进行外挂,实现磁盘扩容,把仓库挂在外挂上. 默认情况下,mvn的配置文件在~/.m2/sett ...

  5. iOS:图片上传时两种图片压缩方式的比较

    上传图片不全面的想法:把图片保存到本地,然后把图片的路径上传到服务器,最后又由服务器把路径返回,这种方式不具有扩展性,如果用户换了手机,那么新手机的沙盒中就没有服务器返回的图片路径了,此时就无法获取之 ...

  6. iOS: 设置App的国际化和本地化

    原文链接:http://www.cocoachina.com/appstore/20160310/15632.html 前言 App的名字设置方式有很多种,如果在App打包上线时不做修改,最终App的 ...

  7. iOS:进度条控件的详细使用

    进度条控件:UIProcessView:UIView   功能:顾名思义,用来显示下载进度或者传输数据进度.   属性: @property(nonatomic) UIProgressViewStyl ...

  8. SQL盲注测试高级技巧

    写在前面: 这篇文章主要写了一些加快盲注速度的技巧和盲注中比较精巧的语句,虽然注入并不是什么新技术了.但是数据库注入漏洞依然困扰着每一个安全厂商,也鞭策着每一个安全从业者不断前进. 正文: 首先来简单 ...

  9. python 调试模式pdb(转)

    标准库的pdb pdb是Python自带的一个库,为Python程序提供了一种交互式的源代码调试功能,包含了现代调试器应有的功能,包括设置断点.单步调试.查看源码.查看程序堆栈等.如果读者具有C或C+ ...

  10. xml文件中配置JDBC源遇到问题 : The reference to entity "characterEncoding" must end with the ';' delimiter

    数据源配置时加上编码转换格式后出问题了: The reference to entity"characterEncoding" must end with the ';' deli ...