本节主要是对handler机制有一个大概的了解,后面的章节还会详细的分析handler机制。

handler产生背景

在介绍handler之前先来介绍下它产生的背景,只有了解了背景才能加深对它的了解。

子线程与主线程通信

子线程与主线程通信,那肯定是一些操作是不能在子线程中进行的,只能在主线程进行。那就从哪些操作需要在主线程中执行说起吧。

ui的绘制/更新只能在主线程
android中ui的绘制/更新只能在主线程中,为啥会有这样的一个规定呢?主要的原因是为了ui绘制/更新的”安全性,一致性“。

假如在子线程中也可以进行ui的绘制/更新,那会有什么问题呢?比如当前有2个子线程:线程A,线程B,同时分别把TextView的内容设置为”hello A“,”hello B“。那这时候界面上显示的TextView的内容就不确定了,有可能显示”hello A“,也有可能显示”hello B“。造成这个的主要原因是:两线程同时设置,并且这俩线程先后执行的顺序是不确定的。

那应该有人就会说,在为TextView设置text的时候,增加同步锁(synchronized)不就可以解决问题了吗?是的这样确实可以解决问题,但又引入了别的问题:绘制效率问题,复杂度问题,容易出现死锁问题等。
绘制效率问题:因为有了锁,那等待,释放锁,线程之间的切换都是开销,这会严重的影响绘制效率。
复杂度问题:整个View体系相应的改变View属性的地方都需要加synchronized,有漏掉的地方就会出现绘制出错的问题。
容易出现死锁问题:因为有了同步机制,那死锁的概率就会大大增加啊,死锁的问题有多严重大家都清楚,界面上会出现卡顿,甚至没办法执行绘制的情况。

所以基于以上的这些问题,ui的绘制/更新在主线程中执行这是最简单有效的方法。

主线程不能有耗时任务
像上面提到的ui的绘制/更新需要在主线程中执行,还有点击事件的分发,四大组件的生命周期方法执行等都是需要在主线程里面执行的。如果主线程里面存在耗时的操作,那产生的问题就大了,比如在Activity的onCreate方法中有耗时操作,那就会影响后面的生命周期的执行,站在用户角度来看的话,整个界面显示很慢,长时间处于白屏状态,这肯定不是一个好的用户体验。

因此耗时的任务就需要放在子线程里面执行(比如网络请求,读取本地文件等等),当子线程执行完毕后,就需要把需要更新view的数据发送给主线程,让主线程帮忙绘制view。

binder线程与主线程通信

在启动Activity时候,AMS(ActivityManagerService简称)会通过binder调用把消息发送给app端,这个时刻是运行在binder线程中的,那后续Activity的初始化,启动等流程肯定是不能继续在binder线程中的,为啥不能继续在binder线程中?主要原因是binder线程的作用是处理binder相关的操作,既然binder操作已经完成了那肯定就需要赶紧把binder线程“解放”出来,让它继续处理其他的binder操作;如若不把binder线程”解放“出来,会影响app端binder的服务,同时Activity启动及四大组件相关的启动操作都会变的复杂,因为需要涉及到”安全性,一致性“相关的问题。

上面提到的子线程与主线程通信binder线程与主线程通信,这只是线程之间通信的其中两个场景,还有很多其他的场景(比如业务内也会有线程之间通信),android设计者,为了开发者更加便利,不用重复的造轮子。因此在这样的背景下设计了handler,handler目的是解决线程之间通信问题

handler原理

生产者消费者模式

先来介绍下生产者消费者模式,为啥要介绍这个模式呢,因为handler的核心原理就是生产者消费者模式。

上图展示的是生产者消费者模式,生产者把数据放入数据缓存区中,消费者从数据缓存区中取数据,生产者可以有多个,消费者也可以有多个,生产者与消费者一般都位于不同的线程。
生产者消费者模式可以衍生出多种结构:多个生产者和多个消费者(消费者处于不同的线程,多个生产者和一个消费者,一个生产者和一个消费者等。

生产者消费者模式实现线程之间通信
最主要是基于共享内存这个机制,一个进程内的内存在线程之间是共享的。

上图的结构是多个生产者和一个消费者的结构,展示了是如何实现线程之间通信的,下面对上图进行介绍:
数据队列:它是线程之间共享的,它主要的目的是存放数据,数据读取器从中拿数据。因为数据队列是多线程之间共享的,因此需要使用同步机制来保证它的安全。
数据读取器:这是我自己取的一个名字,它的主要作用是不断的循环从数据队列中拿数据,拿到数据后交给处理者处理数据。
处理者:这也是我自己去的一个名字,它的主要作用就是处理数据,是生产者消费者模式中的消费者角色。
消费者线程:数据队列,处理者,数据读取器都在这个线程内执行。

当数据队列中没有数据的时候,消费者线程进入wait状态并且释放掉cpu等资源。

当线程1的生产者把数据放入数据队列后,会把处于wait状态的消费者线程唤醒,这时它的数据读取器从数据队列中取到刚刚的数据,再把数据交给处理者处理。这个过程就实现了线程1与消费者线程之间的通信。

handler的核心原理就是生产者消费者模式,基于此基础上进行封装,封装出了Looper,Handler,Message,MessageQueue这些类,那就来介绍下这几个类。

handler核心类

Looper:与上面的数据读取器的功能类似,它的作用就是从MessageQueue中取出Message交给Handler处理,Hanlder处理完毕后,再不断的接着这样的循环此过程。
MessageQueue:它就是上面的数据队列,它的作用就是用来存放Message,以链表结构存放Message的,并且为Looper提供Message,当队列中没有Message的时候线程进入wait状态;当往队列中存放Message后,MessageQueue所在的线程被唤醒,获取到Message交给Looper处理。
Message:与上面的数据相对应,线程之间通过handler通信,传递的数据就是Message
Handler:它就是消费者,与上面的处理者相对应,它的作用是在它对应的线程内处理Message。

总结

本节主要介绍了handler的产生背景和handler的原理,这节只是一个概览,handler的知识是很多的,在后面的章节中会一一介绍,下面用一张图来做一个总结

handler机制--handler概览相关推荐

  1. 【Android】Handler 机制 ( Handler | Message | Looper | MessageQueue )

    文章目录 I . Handler 机制简介 II . Handler 机制 Handler Message Looper MessageQueue 四组件对应关系 III . Handler ( 消息 ...

  2. 【Android 异步操作】Handler 机制 ( Handler 常用用法 | HandlerThread 简介 | HandlerThread 源码注释分析 )

    文章目录 一.Handler 常用用法 二.HandlerThread 简介 三.HandlerThread 源码 一.Handler 常用用法 主线程 Handler 主要作用 : Looper 和 ...

  3. handler机制--Handler使用

    这节介绍Handler类使用相关的知识(以下分析都是基于android 12代码) 1. Handler的使用 1.1 创建Handler实例 创建Handler实例直接调用相应的构造函数即可,如下: ...

  4. Handler 机制分析

    android 子线程和UI线程的交互主要使用Handler的方法进行通信.本文分析Handler机制 Handler 如何使用? Handler的使用比较简单 public class MainAc ...

  5. Android面试——Handler 机制

    Android面试--Handler 机制 一.Handler机制 Handler机制围绕的三个点 1.Handler负责消息的发送和接受 发送给消息MessageQueue和接受Looper返回的消 ...

  6. Android消息机制Handler用法

    这篇文章介绍了Android消息机制Handler用法总结,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 1.简述 Handler消息机制主要包括: Messa ...

  7. android Handler机制之ThreadLocal详解

    概述 我们在谈Handler机制的时候,其实也就是谈Handler.Message.Looper.MessageQueue之间的关系,对于其工作原理我们不做详解(Handler机制详解). Messa ...

  8. Android多线程:深入分析 Handler机制源码(二)

    前言 在Android开发的多线程应用场景中,Handler机制十分常用 接下来,深入分析 Handler机制的源码,希望加深理解 目录 1. Handler 机制简介 定义 一套 Android 消 ...

  9. Android之异步消息处理机制Handler源码解析

    转载请标明出处: http://blog.csdn.net/hai_qing_xu_kong/article/details/76083113 本文出自:[顾林海的博客] 个人开发的微信小程序,目前功 ...

最新文章

  1. BZOJ2428[HAOI2006]均分数据——模拟退火
  2. OpenGL中的轨迹球问题
  3. Go语言在扫码支付系统中的成功实践
  4. C#利用反射将Datatable转化为指定实体类ListT
  5. Jupyter notebook 使用多个Conda 环境
  6. c语言 去掉双引号_技术分享|浅谈C语言陷阱和缺陷
  7. vivado和modelsim联合仿真实现奇分频
  8. 《智能优化算法及其MATLAB实现》书籍出版啦
  9. 性能高的tftp服务器,tftp服务器软件
  10. python实现钉钉群自动警报
  11. 十分好用的拓扑图插件JTopo
  12. 解决:3Dmax 渲染后任意点击就卡住不能点击,UI界面冻结
  13. 1987 三 比尔·哈利 Bill Haley
  14. 【软件测试】男生vs女生,谁更加适合?没有你发现不了的bug......
  15. 数论-卢卡斯定理(lucas)与拓展卢卡斯定理 (exlucas)
  16. php获取日期为星期几,php获取日期是星期几
  17. 【Experience Summary】出差布置产线
  18. python进行数据预处理(最大最小值规范化、零均值规范化、剔除奇异值、去噪、曲线拟合)
  19. QT串口动态实时显示大量数据波形曲线(一)========“串口设置与ui界面添加(灯与按钮)”
  20. Spring事务的实现原理

热门文章

  1. 计算机组成原理——奇偶校验,海明校验,循环冗余校验
  2. 小沙的remake(牛客)排序+ 树状数组 + dp
  3. 单片机“左移右移理论”,详解
  4. springboot+cas单点登录
  5. matlab三元方程拟合,3元函数拟合及结果.docx
  6. Ubuntu磁盘分区
  7. 小程序中的axio——flyio的使用
  8. PHP 函数、类声明和调用
  9. 小白兔写话_可爱的小白兔二年级写话
  10. Pairwise(FCC算法)