第十章  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. 18) maven 项目结构:继承

    Project Inheritance [ɪn'herɪt(ə)ns] https://maven.apache.org/guides/introduction/introduction-to-the ...

  2. crontab条目包含%号问题

    crontab条目中包含%号,最常见的取时间,如:date +%d, 对%需要使用\进行转义,否则不能按预期执行,正确做法为: * * * * * echo "`date +\%d`&quo ...

  3. bind研究(一)转载

    ## 阅读数:6537 最近自学JavaScript,学到bind方法这块儿有些地方不太明白,自己就查了些资料,结合自己的理解写了这篇文章以备后面回顾用...其实应该还是搬砖为主吧. 什么是this对 ...

  4. Video Processing and Communications:(视频处理和通信)

    https://max.book118.com/html/2017/1010/136711526.shtm Application of (GAN) of AI faceswap in Music V ...

  5. js中对String去空格

    str为要去除空格的字符串: 去除所有空格: str = str.replace(/\s+/g,""); 去除两头空格: str = str.replace(/^\s+|\s+$/ ...

  6. 三种初步简易的方法求解数值问题 of C++

    1. “二分法解方程” 在二分法中,从区间[a,b]开始,用函数值f(a)与f(b)拥有相反的符号.如果f在这个区间连续,则f的图像至少在x=a,x=b之间穿越x轴一次,因此方程f(x)=0在[a,b ...

  7. js五道经典练习题--第四道qq好友列表

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...

  8. LigerUi中为Grid表加上序号,并调整适当宽度!(实例)

    LigerUi中为Grid表加上序号,并调整适当宽度!(实例) dataAction: 'server', pageSize: 20, toolbar: {},           url: 'ndl ...

  9. HDU 1556 区间查询

    Color the ball Time Limit: 3000 MS Memory Limit: 32768 KB 64-bit integer IO format: %I64d , %I64u Ja ...

  10. Kali Linux渗透测试实战 2.2 操作系统指纹识别

    目录 2.2 操作系统指纹识别 2.2.1 Banner抓取 2.2.2 TCP 和 ICMP 常规指纹识别技术 TCP数据报格式 ICMP首部格式 TTL与TCP窗口大小 FIN探测 BOGUS f ...