第十章  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开发艺术探索学习笔记(十)的更多相关文章

  1. Android开发艺术探索学习笔记(三)

    第三章  View的事件体系 3.1 View基础知识 3.1.1 什么是view View 是Android中所有控件的基类,是一种界面层的控件的一种抽象,它代表了一个控件. 3.1.2 View的 ...

  2. Android开发艺术探索学习笔记(十一)

    第十一章  Android的线程和线程池 从用途上来说,线程分为子线程和主线程,主线程主要处理和界面相关的事情,而子线程往往用于执行耗时的操作.AsyncTask,IntentService,Hand ...

  3. Android开发艺术探索学习笔记(六)

    第六章 Android的Drawable  Drawable的优点:使用简单,比自定义view的成本要低:非图片类型的Drawable占用空间小,有利于减小APK安装包的大小. 6.1Drawable ...

  4. Android开发艺术探索学习笔记(四)

    第四章 View的工作原理 4.1初识ViewRoot和DecorView ViewRoot是连接WindowManager和DecorView的纽带,View的三大流程均是通过ViewRoot来完成 ...

  5. Android开发艺术探索学习笔记(一)

    第一章 Activity的生命周期和启动模式 1.1Activity的生命周期全面解析 1.1.1典型情况下的生命周期分析 (1)在两个Activity进行切换时,当前的Activity的onPaus ...

  6. Android开发艺术探索读书笔记——01 Activity的生命周期

    http://www.cnblogs.com/csonezp/p/5121142.html 新买了一本书,<Android开发艺术探索>.这本书算是一本进阶书籍,适合有一定安卓开发基础,做 ...

  7. Android开发艺术探索读书笔记——进程间通信

    1. 多进程使用场景 1) 应用某些模块由于特殊需求须要执行在单独进程中. 如消息推送,使消息推送进程与应用进程能单独存活,消息推送进程不会由于应用程序进程crash而受影响. 2) 为加大一个应用可 ...

  8. [读书笔记]《Android开发艺术探索》第十五章笔记

    Android性能优化 Android不可能无限制的使用内存和CPU资源,过多的使用内存会导致内存溢出,即OOM. 而过多的使用CPU资源,通常是指做大量的耗时任务,会导致手机变的卡顿甚至出现程序无法 ...

  9. android开发艺术探索学习 之 结合Activity的生命周期了解Activity的LaunchMode

    转载请标明出处: http://blog.csdn.net/lxk_1993/article/details/50749728 本文出自:[lxk_1993的博客]: 首先还是先介绍下Activity ...

随机推荐

  1. MIT molecular Biology 笔记11 位点特异性重组 和 DNA转座

    位点特异性重组 和 DNA转座 视频 https://www.bilibili.com/video/av7973580/ 教材 Molecular biology of the gene 7th ed ...

  2. C++指针一

    指针也是变量,占有内存空间,用来保存内存地址. 指针也是一种数据类型,指针是一种数据类型,是指它所致内存空间的数据类型. 指针变量和它指向的内存块是两个不同的概念 *p操作内存 在指针声明时,*号表示 ...

  3. DeepFace和GAN

    由于换脸技术的影响,现在造假视频的成本越来越低.AI换脸视频也越来越热门,甚至有一些已经达到了以假乱真的程度.虽然有明星反对表示无奈,可是.... 据报道,2018年,arXiv上发布了902篇GAN ...

  4. day28(ajax之js原生代码实现)

    ajax ajax:异步页面无刷新技术 AJAX:异步的 JavaScript And XML. * 使用的是老的技术,用的是新的思想. AJAX的功能:完成页面的局部刷新,不中断用户的体验. XML ...

  5. gcc和vs在c的一些区别

    1.switch中每个标签后面的命令在gcc中需要{}括起来以指明作用域. 2._itoa是非标准的c和c++扩展函数,在linux下可以使用sprintf(string,   "%d &q ...

  6. 移动端 - Android客户端性能测试常见指标

    rom版本的性能测试 一般关注功耗(不过 rom 版本的功耗测试跟应用的功耗测试会有所差异,当然只是用例设计方面的差异,工具仍然采用安捷伦电源仪进行) 应用的性能测试 包括很多测试项,如启动时间.内存 ...

  7. (记忆化搜索)数塔 (zznu 1271)

    http://acm.zznu.edu.cn/problem.php?id=1271 1271: 数塔 时间限制: 1 Sec  内存限制: 128 MB提交: 109  解决: 78[提交][状态] ...

  8. [javascript-snippet]使用javascript+html5实现图片的灰度处理

    // 源码出自:潇湘夜雨<!DOCTYPE> <html> <head> <meta charset="utf-8"/> </ ...

  9. 11.Scrapy登录

    Request Request 部分源码: # 部分代码 class Request(object_ref): def __init__(self, url, callback=None, metho ...

  10. 停止一个java的线程执行

    找了一个停止线程运行的方法,代码如下: public class stopThread extends Thread { private volatile boolean stop = false; ...