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. Redis简单入门认识

    写在前面: 最近一直都在按照老大的学习路线来进行学习,这几天看了下redis,从刚开始的摸不着头脑,到后面慢慢的查资料,对其逐渐有了简单的了解,也通过一个与ssm框架整合的小demo去动手实践 了,知 ...

  2. SpringBoot 整合 Jpa

    项目目录结构 pom文件 <?xml version="1.0" encoding="UTF-8"?> <project xmlns=&quo ...

  3. Redis源码解析之ziplist

    Ziplist是用字符串来实现的双向链表,对于容量较小的键值对,为其创建一个结构复杂的哈希表太浪费内存,所以redis 创建了ziplist来存放这些键值对,这可以减少存放节点指针的空间,因此它被用来 ...

  4. ERROR 1044: Access denied for user: 'songyan' to database 'yikexiao' 的错误。

    问题描述:新买的服务器,刚安装了mysql,创建了一个用户,也忘记了给他分配了什么权限,今天在建库的时候出现了这个问题. 出错原因:度娘告诉我是因为songyan用户没有建库的权限报的错. 解决: ( ...

  5. AIM Tech Round (Div. 1) D. Birthday 数学 暴力

    D. Birthday 题目连接: http://www.codeforces.com/contest/623/problem/D Description A MIPT student named M ...

  6. Server-side Query interception with MS SQL Server

      up vote15down votefavorite 5 I'm researching into intercepting queries that arrive at the SQL Serv ...

  7. Code Review: 超越“审、查、评”的代码回顾

    http://news.cnblogs.com/n/532148/ 文/TWInsights-伍斌 Code Review 应该是软件开发团队“共同学习.识别模式和每日持续”的过程,而不是带有“审.查 ...

  8. 解决Centos运行yum 报错:坏的解释器

    # ll /usr/bin/python python python2 python2.6 python2.7 python.bak 1,这里先备份原来的/usr/bin/python 为python ...

  9. [ Android Memory] MAT查看图片资源

    参考: http://stackoverflow.com/questions/12709603/mat-eclipse-memory-analyzer-how-to-view-bitmaps-from ...

  10. Kubernetes Pod日志太大导致空间问题

    在log-driver是json-file的模式下,容器的日志存放在/var/lib/docker/containers/下面,是以container_id-json.log文件存放 但缺省方式下,l ...