Android开发艺术探索学习笔记(十)
第十章 Android的消息机制
面试中经常会被问到的一个问题:handler是如何在子线程和主线程中进行消息的传递的,这个问题通过了解Android的消息机制可以得到一个准确的答案。
Android的消息机制主要就是指Handler的运行机制,Handler的运行需要底层的MessageQueue和Looper的支撑。需要理解两个概念:
MessageQueue:消息队列,通过单链表的数据结构来存储一组消息,以队列的形式对外提供插入和删除的工作。
Looper:消息循环,以无限循环的方式查找MessageQueue是否有新消息,有的话就处理消息,否则一直等待。
如果需要使用Handler就必须为Handler所在的线程创建Looper,主线程在创建的时候会自动初始化Looper,而子线程默认是没有Looper的,这就是在主线程默认可以使用Handler而子线程中默认不能使用Handler的原因。
Android系统之所以提供Handler,主要就是为了解决在子线程中无法访问UI的矛盾。之所以不允许在子线程中访问UI,主要是考虑到控件不是线程安全的,因为多个线程访问控件可能会导致UI控件处于不可预期的状态。
Handler,MessageQueue,Looper的工作工程如下图所示:

首先Handler通过post方法将一个Runnable或者send方法将一个消息投递到handler内部的Looper中,其实post方法最后也是通过send方法来完成的,所以以send方法为例,当send方法被调用后,它会调用MessageQueue中的enqueueMessage方法将这个消息放入MessageQueue中,此时looper发现MessageQueue中存在新消息,会开始处理这个消息,最终Handler中的handleMessage方法就会被调用,因为Looper是运行在创建Handler所在的线程中,这样一来就完成了消息在子线程和主线程中的传递。
MessageQueue主要包含两个操作,插入(enqueueMessage)和读取(next),读取本身会伴随这删除操作。enqueueMessage方法的作用是往消息队列中插入一条消息,next方法的作用是从消息队列中取出一条消息并将其从消息队列中移除。
Looper的主要作用就是不断的从MessageQueue查看是否有新消息,如果没有就一直阻塞在那里。
子线程中如果需要使用Handler那就必须先为子线程创建一个Looper,通过Looper.preper()可以为当前线程创建一个
Looper,然后通过Looper.loop()来开启消息循环,当使用完毕后需要调用Looper.quit()来终止消息循环,否则由于
Looper内部是一个死循环导致子线程会一直处于等待的状态,也就是线程不能结束。
Android开发艺术探索学习笔记(十)的更多相关文章
- Android开发艺术探索学习笔记(三)
第三章 View的事件体系 3.1 View基础知识 3.1.1 什么是view View 是Android中所有控件的基类,是一种界面层的控件的一种抽象,它代表了一个控件. 3.1.2 View的 ...
- Android开发艺术探索学习笔记(十一)
第十一章 Android的线程和线程池 从用途上来说,线程分为子线程和主线程,主线程主要处理和界面相关的事情,而子线程往往用于执行耗时的操作.AsyncTask,IntentService,Hand ...
- Android开发艺术探索学习笔记(六)
第六章 Android的Drawable Drawable的优点:使用简单,比自定义view的成本要低:非图片类型的Drawable占用空间小,有利于减小APK安装包的大小. 6.1Drawable ...
- Android开发艺术探索学习笔记(四)
第四章 View的工作原理 4.1初识ViewRoot和DecorView ViewRoot是连接WindowManager和DecorView的纽带,View的三大流程均是通过ViewRoot来完成 ...
- Android开发艺术探索学习笔记(一)
第一章 Activity的生命周期和启动模式 1.1Activity的生命周期全面解析 1.1.1典型情况下的生命周期分析 (1)在两个Activity进行切换时,当前的Activity的onPaus ...
- Android开发艺术探索读书笔记——01 Activity的生命周期
http://www.cnblogs.com/csonezp/p/5121142.html 新买了一本书,<Android开发艺术探索>.这本书算是一本进阶书籍,适合有一定安卓开发基础,做 ...
- Android开发艺术探索读书笔记——进程间通信
1. 多进程使用场景 1) 应用某些模块由于特殊需求须要执行在单独进程中. 如消息推送,使消息推送进程与应用进程能单独存活,消息推送进程不会由于应用程序进程crash而受影响. 2) 为加大一个应用可 ...
- [读书笔记]《Android开发艺术探索》第十五章笔记
Android性能优化 Android不可能无限制的使用内存和CPU资源,过多的使用内存会导致内存溢出,即OOM. 而过多的使用CPU资源,通常是指做大量的耗时任务,会导致手机变的卡顿甚至出现程序无法 ...
- android开发艺术探索学习 之 结合Activity的生命周期了解Activity的LaunchMode
转载请标明出处: http://blog.csdn.net/lxk_1993/article/details/50749728 本文出自:[lxk_1993的博客]: 首先还是先介绍下Activity ...
随机推荐
- CentOS和Ubuntu哪个好?
CentOS(Community ENTerprise Operating System)是Linux发行版之一,它是来自于Red Hat Enterprise Linux依照开放源代码规定释出的源代 ...
- POJ3189 Steady Cow Assignment
Steady Cow Assignment Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 6817 Accepted: ...
- AngularJS 指令中的 replace:true
默认值是fasle,模板会被当作子元素插入到调用此指令的元素内部. <my-directive></my-directive> myModule.directive(" ...
- RxSwift学习笔记6:Subjects/PublishSubject/BehaviorSubject/ReplaySubject/Variable
// 从前面的几篇文章可以发现,当我们创建一个 Observable 的时候就要预先将要发出的数据都准备好,等到有人订阅它时再将数据通过 Event 发出去. // 但有时我们希望 Observabl ...
- HDU 4920 矩阵乘积 优化
Matrix multiplication Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/ ...
- ADO.NET系列之事务和调用存储过程
ADO.NET系列之Connection对象 ADO.NET系列之Command对象 ADO.NET系列之DataAdapter对象 ADO.NET系列之事务和调用存储过程 前几篇我们介绍了Conne ...
- NET npoi 保存文件
npoi完整代码:NET npoi帮助类 public static void DataTableToExcel(List<DataTable> dataTables, string fi ...
- C#中解析JSON数据,并获取到其中的值
1.应需求创建一个Json字符串 string json = "[{'Name':'张三','age':'20','Data':{'ID':100,'heigh':'180','weight ...
- UOJ#419. 【集训队作业2018】圆形(格林公式)
题面 传送门 题解 首先您得会用格林公式计算圆的面积并 这里只需要动态维护一下圆弧就可以了 时间复杂度\(O(n^2\log n)\) //minamoto #include<bits/stdc ...
- VNC黑屏解决办法
在Linux里安装配置完VNC服务端,发现多用户登陆会出现黑屏的情况,具体的现象为:客户端可以通过IP与会话号登陆进入系统,但登陆进去是漆黑一片,除了一个叉形的鼠标以外,伸手不见五指. 原因:用户的V ...