Handler进阶之sendMessage原理探索

Handler进阶之sendMessage原理探索Handler 进阶之 sendMessage 本文主要进一步的探索 Handler 主要介绍下 Handler 是如何发送消息的 用过 Handler 的想必对一下几个方法都不会陌生 sendMessage Messagemsg 立刻发送消息 sendMessageA Messagemsg longatTime 在某个时间点发送消息 sendMessageD

Handler进阶之sendMessage


sendMessage(Message msg);//立刻发送消息 sendMessageAtTime(Message msg, long atTime);//在某个时间点发送消息 sendMessageDelayed(Message msg, long delayedTime);//在当前时间点延迟一段时间发送消息 

 以上是三个Handler发送消息的方法,区别在于发送的时间点不一致,但其实三个方法在最终都是执行Handler内的同一个方法,只是在参数上稍有区别:

public final boolean sendMessageDelayed(Message msg, long delayMillis) { 
     if (delayMillis < 0) { 
     delayMillis = 0; } return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis); } sendMessage(Message msg); //对应 sendMessageDelayed(msg, 0)sendMessageAtTime(Message msg, long atTime); //对应 sendMessageDelayed(msg, atTime) sendMessageDelayed(Message msg, long delayedTime); //对应 sendMessageDelayed(msg, SystemClock.uptimeMillis() + delayedTime) 

Handler消息机制原理全方面解读

 此处直接看Message放入MessageQueue的过程:

boolean enqueueMessage(Message msg, long when) { ...//代码较多,省去了部分抛出异常的代码 synchronized (this) { ... 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.next prev.next = msg; } // We can assume mPtr != 0 because mQuitting is false. if (needWake) { nativeWake(mPtr); } } return true; } 

 重点就在if-else这里,将它们一个一个拆开来看:

if (p == null || when == 0 || when < p.when) {//p是当前MessageQueue队首Message // New head, wake up the event queue if blocked. msg.next = p; mMessages = msg; needWake = mBlocked; } 
 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.next prev.next = msg; 

之所以写这篇文章主要是为了解答两个问题。

  1. sendMessageDelayed是如何实现延时发送消息的?
  2. sendMessageDelayed是通过阻塞来达到了延时发送消息的结果,那么会不会阻塞新添加的Message?

总结:

  1. Handler在发送消息的时候,MessageQueue里的消息是按照发送时间点从小到大排列的,
    如果最近的Message未到达发送的时间则阻塞。
  2. 新加入的数据会根据时间点的大小判断需要插入的位置,同时还需要判断是否需要唤醒线程去发送当前的队首的消息。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/232076.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 一个15年ABAP老兵的建议:了解这些基础知识,对ABAP开发有百利而无一害

    一个15年ABAP老兵的建议:了解这些基础知识,对ABAP开发有百利而无一害SAPNetweaver 应用服务器是 SAPABAP 应用开发和运行平台 ABAP 开发人员在上面可以专注于具体业务逻辑的开发 凡涉及到更底层的基础设施相关任务 比如请求的负载均衡 进程的派生 同步和调度 内存管理 服务器多实例间缓存同步等等 统统交由 Netweaver 平台本身处理 如此一来 一个 ABAP 开发人员 即使不具备精深的计算机组成原理 操作系统 计算机网络等领域知识 也能胜任 SAP 应用的开发工作 本文详细介绍了 ABAP 服务器的各大组成部分和其职责所在 httpshttpsht

    2025年11月20日
    5
  • 双线性插值算法推导及代码实现

    双线性插值算法推导及代码实现双线性插值,是一种比较重要的插值方法,尤其在数字图像处理领域。本篇博文分为三个部分:一是双线性插值的算法推导,二是双线性插值的算法实现,三是算法的运行结果。

    2022年6月8日
    31
  • 极路由2刷机_极路由刷固件有什么用

    极路由2刷机_极路由刷固件有什么用绕过官方的ROOT查了一下root教程,如果还需要保留保修,则需要自己想办法回退版本,下载搜狐插件到sd卡,找个linux系统修改sd卡上程序的执行权限,然后才能开启ssh,具体的方法可

    2022年8月3日
    5
  • 警告:为了安全请不要随意将ASP.Net的validateRequest=”false” .

    警告:为了安全请不要随意将ASP.Net的validateRequest=”false” .ASP.Net1.1后引入了对提交表单自动检查是否存在XSS(跨站脚本攻击)的能力。当用户试图用之类的输入影响页面返回结果的时候,ASP.Net的引擎会引发一个HttpRequestValidationExceptioin。默认情况下会返回如下文字的页面:ServerErrorin’/YourApplicationPath’ApplicationApot

    2022年6月5日
    29
  • Swift如何给应用添加3D Touch菜单

    Swift如何给应用添加3D Touch菜单

    2021年5月27日
    148
  • 2021全国大学生电子设计竞赛–电源–三相逆变(硬件)「建议收藏」

    2021全国大学生电子设计竞赛–电源–三相逆变(硬件)「建议收藏」废话不多说,直接上电路!三相逆变系统的框架如下::那么,降压电路不用多说,网上多得是1、下面说一下逆变驱动电路,也是通篇一律,这里贴上电路图,2、LC滤波器很多人会问我,LC如何选取,还有人在问,为啥我做出来之后发现电感在出声?答:第一个问题,网上可以搜得到,就是一个公式,以基波50HZ进行计算就行。第二个问题,有时候电感明明很大了,仍然出声音,其实那不是电感的问题,由于瓷片电容本身结构的问题,所以就睡导致在高频下的振荡出声,如果换成安规电容或者CBB就会…

    2022年5月25日
    42

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号