关于handler消息处理机制,只要一提到,相信作为一个android工程师,脑海就会有这么一个流程

大家都滚瓜烂熟了,但别人问到几个问题,很多人还是栽到这个“烂”上面,比如:

  • 一个线程是如何对应一个Lopper的?
  • messageQueue是如何做到线程安全的?
    首先先Looper看一段代码:
private static void prepare(boolean quitAllowed) {if (sThreadLocal.get() != null) {throw new RuntimeException("Only one Looper may be created per thread");}sThreadLocal.set(new Looper(quitAllowed));}

这里先通过sThreadLocal.get()去获取这个Looper, 获取不到再去通过new (Looper(quitAllowed))去创建Looper()对象。再来看看这个构造函数:

private Looper(boolean quitAllowed) {mQueue = new MessageQueue(quitAllowed);mThread = Thread.currentThread();}

构造函数私有的,只能通过Prepare去初始化,这里就形成了一个关系,一个Looper 对应一个MessageQueue。

回过头再来分析,线程是如何和Looper对应的。

/*** Return the Looper object associated with the current thread.  Returns* null if the calling thread is not associated with a Looper.*/public static @Nullable Looper myLooper() {return sThreadLocal.get();}

在Prepare()的时候给sThreadLocal.set(Looper), 获取Looper的对象是通过sThreadLocal.get()返回的,下面看看sThreadLocal:

 // sThreadLocal.get() will return null unless you've called prepare().static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();

这是一个静态成员变量所有的Looper对象共有属性。
sTreadLocal保存线程的唯一值,这样就保证一个线程对应一个looper.

至于MessageQueue的线程同步,会有奇葩的人问到,无非就是syncnized关键字,或者加锁。

boolean enqueueMessage(Message msg, long when) {if (msg.target == null) {throw new IllegalArgumentException("Message must have a target.");}if (msg.isInUse()) {throw new IllegalStateException(msg + " This message is already in use.");}synchronized (this) {if (mQuitting) {IllegalStateException e = new IllegalStateException(msg.target + " sending message to a Handler on a dead thread");Log.w(TAG, e.getMessage(), e);msg.recycle();return false;}msg.markInUse();msg.when = when;Message p = mMessages;boolean needWake;if (p == null || when == 0 || when < p.when) {// New head, wake up the event queue if blocked.msg.next = p;mMessages = msg;needWake = mBlocked;} else {// Inserted within the middle of the queue.  Usually we don't have to wake// up the event queue unless there is a barrier at the head of the queue// and the message is the earliest asynchronous message in the queue.needWake = mBlocked && p.target == null && msg.isAsynchronous();Message prev;for (;;) {prev = p;p = p.next;if (p == null || when < p.when) {break;}if (needWake && p.isAsynchronous()) {needWake = false;}}msg.next = p; // invariant: p == prev.nextprev.next = msg;}// We can assume mPtr != 0 because mQuitting is false.if (needWake) {nativeWake(mPtr);}}return true;}

这里用的是一个加锁的方式。
在Loop.loop中有一死循环,那么当没有消息时,主线程不可能死掉吧?
“`
在主线程的MessageQueue没有消息时,便阻塞在loop的queue.next()中的nativePollOnce()方法里,此时主线程会释放CPU资源进入休眠状态,直到下个消息到达或者有事务发生,通过往pipe管道写端写入数据来唤醒主线程工作。这里采用的epoll机制,是一种IO多路复用机制,可以同时监控多个描述符,当某个描述符就绪(读或写就绪),则立刻通知相应程序进行读或写操作,本质同步I/O,即读写是阻塞的。 所以说,主线程大多数时候都是处于休眠状态,并不会消耗大量CPU资源。

还有什么关于handler的问题,希望大家可以提出来。

handler 消息处理机制相关推荐

  1. Handler消息处理机制详解

    之前一直只知道handler如何使用,不知道其中的工作原理,趁着新版本提测阶段比较空闲,及时做一个总结. 先看一下Google官方文档关于handler的解释: A Handler allows yo ...

  2. Handler消息处理机制

    一.核心类 1.Looper 1.变量 ThreadLocal sTreadLoad; MesseageQuene mQueue; Tread mThread; 2.操作集 Looper.Prepar ...

  3. Android Handler 异步消息处理机制的妙用 创建强大的图片载入类

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38476887 ,本文出自[张鸿洋的博客] 近期创建了一个群.方便大家交流,群号: ...

  4. android的消息处理机制(图+源码分析)——Looper,Handler,Message

    android源码中包含了大量的设计模式,除此以外,android sdk还精心为我们设计了各种helper类,对于和我一样渴望水平得到进阶的人来说,都太值得一读了.这不,前几天为了了解android ...

  5. 【转】android的消息处理机制(图+源码分析)——Looper,Handler,Message

    原文地址:http://www.cnblogs.com/codingmyworld/archive/2011/09/12/2174255.html#!comments 作为一个大三的预备程序员,我学习 ...

  6. Android多线程----异步消息处理机制之Handler

    虽然是国庆佳节,但也不能停止学习的脚步,我选择在教研室为祖国母亲默默地庆生. 关于Android的多线程知识,请参考本人之前的一篇博客:Android 多线程----AsyncTask异步任务详解 在 ...

  7. Android应用程序消息处理机制(Looper、Handler)分析(1)

    Android应用程序是通过消息来驱动的,系统为每一个应用程序维护一个消息队例,应用程序的主线程不断地从这个消息队例中获取消息(Looper),然后对这些消息进行处理(Handler),这样就实现了通 ...

  8. Android 应用程序消息处理机制(Looper、Handler)分析

    Android应用程序是通过消息来驱动的,系统为每一个应用程序维护一个消息队例,应用程序的主线程不断地从这个消息队例中获取消息(Looper),然后对这些消息进行处理(Handler),这样就实现了通 ...

  9. Android之多线程----异步消息处理机制之Handler详解

    一.handler的引入: 我们都知道,Android UI是线程不安全的,如果在子线程中尝试进行UI操作,程序就有可能会崩溃.相信大家在日常的工作当中都会经常遇到这个问题,解决的方案应该也是早已烂熟 ...

最新文章

  1. 主成分分析(PCA) C++ 实现
  2. php mysql购物车_php mysql购物车实现程序
  3. 达摩院2022年十大科技趋势发布:AI for Science刚开始,大模型进入冷静期
  4. 蓝桥杯C/C++ 带分数
  5. 笔记-高项案例题-2019年上-计算题
  6. 探析“Java序列化”之serialVersionUID
  7. 可以这样给DataGrid加个序号列。
  8. 马上开课 | 第 3 期临床基因组家系分析,助力发表Case Report
  9. 理解SQL Server中的权限体系(下)----安全对象和权限
  10. (C++)wchar_t 转 string / TCHAR转为char/判断是否进程运行/获得目标进程的入口
  11. 添加文件夹语音_微信语音导出方法大全,微信群语音转发只需3步
  12. redis-bitmap 命令使用的一些帖子
  13. 软交换协议比较和发展趋势 (SIP-T和SIP-I的比较)
  14. 2、开关灯、选项卡、隔行换色
  15. IDEA搭建SpringMVC+Spring+Mybatis项目
  16. dell保修及其升级3CC
  17. CTPN算法简单解析
  18. python三维图旋转_python中的三维图像旋转
  19. 强烈推荐这些值得下载的神仙工具,每一个都让人惊喜
  20. 园区3D可视化三维展示系统解决方案

热门文章

  1. 数据可视化【四】Bar Chart
  2. cf#582div3 D——暴力
  3. 单链表逆序的多种方式
  4. IDEA自动生成 构造方法 get set方法
  5. 万字总结!springcloud分布式限流
  6. 从零开始系统化学Android,值得收藏!
  7. 揭秘!双非渣本Android四年磨一剑,学习路线+知识点梳理
  8. eclipse手动添加SVN插件
  9. 欧拉路HDU3018
  10. 使用VB.net建立excel文件