handler解析(4)-Message及Message回收机制
Message中可以携带的信息
Message中可以携带的数据比较丰富,下面对一些常用的数据进行了分析。
/*** 用户定义的消息代码,以便当接受到消息是关于什么的。其中每个Hanler都有自己的命名控件,不用担心会冲突*/ public int what;
/*** 如果你只想存很少的整形数据,那么可以考虑使用arg1与arg2,* 如果需要传输很多数据可以使用Message中的setData(Bundle bundle)*/public int arg1;
/*** 如果你只想存很少的整形数据,那么可以考虑使用arg1与arg2,* 如果需要传输很多数据可以使用Message中的setData(Bundle bundle)*/public int arg2;
/*** 发送给接受方的任意对象,在使用跨进程的时候要注意obj不能为null*/public Object obj;
/*** 在使用跨进程通信Messenger时,可以确定需要谁来接收*/public Messenger replyTo;
/*** 在使用跨进程通信Messenger时,可以确定需要发消息的uid*/public int sendingUid = -1;
/*** 如果数据比较多,可以直接使用Bundle进行数据的传递*/Bundle data;
创建消息的方式
官方建议使用Message.obtain()系列方法来获取Message实例,因为其Message实例是直接从Handler的消息池中获取的,可以循环利用,不必另外开辟内存空间,效率比直接使用new Message()创建实例要高。其中具体创建消息的方式,我已经为大家分好类了。具体分类如下:
//无参数
public static Message obtain() {...}
//带Messag参数
public static Message obtain(Message orig) {}
//带Handler参数
public static Message obtain(Handler h) {}
public static Message obtain(Handler h, Runnable callback){}
public static Message obtain(Handler h, int what){}
public static Message obtain(Handler h, int what, Object obj){}
public static Message obtain(Handler h, int what, int arg1, int arg2){}
public static Message obtain(Handler h, int what,int arg1, int arg2, Object obj) {}
其中在Message的obtain带参数的方法中,内部都会调用无参的obtain()方法来获取消息后。然后并根据其传入的参数,对Message进行赋值。(关于具体的obtain方法会在下方消息池实现原理中具体描述)
消息池实现原理
既然官方建议使用消息池来获取消息,那么在了解其内部机制之前,我们来看看Message中的消息池的设计。具体代码如下:
private static final Object sPoolSync = new Object();//控制获取从消息池中获取消息。保证线程安全
private static Message sPool;//消息池
private static int sPoolSize = 0;//消息池中回收的消息数量
private static final int MAX_POOL_SIZE = 50;//消息池最大容量
// sometimes we store linked lists of these things@UnsupportedAppUsage/*package*/ Message next;public static Message obtain() {synchronized (sPoolSync) {if (sPool != null) {Message m = sPool;sPool = m.next;m.next = null;m.flags = 0; //重新标识当前Message没有使用过sPoolSize--;return m;}}return new Message();//如果为空直接返回}
从中我们发现如果sPool如果不为null,则返回直接new一个Message返回,整个方法结束,那么sPool是什么,sPool是一个message,从源码中我们可以发现sPool其实就相当于一个头指针,指向缓存池中第一个缓存的Message,如果sPool不为null则说明缓存池中存在空闲的Message,返回缓存池中空闲的message,然后sPool执行下一个缓存message对象,然后将msg.next重置为0,整体代码过下来,我们发现Message的缓存池其实就是用了一个数据结构-单向链表。具体流程如图:
这块就很明显是消息池的取出了,那么它的存是在哪里呢,全局搜sPool,我们发现在recycleUncheck中有实现
/*** Recycles a Message that may be in-use.* Used internally by the MessageQueue and Looper when disposing of queued Messages.*/@UnsupportedAppUsagevoid recycleUnchecked() {// Mark the message as in use while it remains in the recycled object pool.// Clear out all other details.flags = FLAG_IN_USE;what = 0;arg1 = 0;arg2 = 0;obj = null;replyTo = null;sendingUid = UID_NONE;workSourceUid = UID_NONE;when = 0;target = null;callback = null;data = null;synchronized (sPoolSync) {if (sPoolSize < MAX_POOL_SIZE) {next = sPool;sPool = this;sPoolSize++;}}}
然后这块代码又是在recycle中调用的
/*** Return a Message instance to the global pool.* <p>* You MUST NOT touch the Message after calling this function because it has* effectively been freed. It is an error to recycle a message that is currently* enqueued or that is in the process of being delivered to a Handler.* </p>*/public void recycle() {if (isInUse()) {if (gCheckRecycle) {throw new IllegalStateException("This message cannot be recycled because it "+ "is still in use.");}return;}recycleUnchecked();}
这块首先判断消息是否在使用之中,如果在使用之中,继续判断gCheckRecycle,gCheckRecycle的默认值是true,如果不在使用之中,最后会走进recycleUnchecked。
然后来分析recycleUnChecked
一开始,把这个消息所有成员赋值成最初的状态,FLAG_IN_USE的值是1一开始说了Message的flags表示这个Message有没有在使用,1表示在池中,等待复用,0表示正在被使用。重点看同步锁中的代码。
假设全局池没有元素时,我们将第一个消息放到池中,sPool一开始是NULL,next指向了sPool,所以此时的消息的sPool和next都是NULL,然后sPool指向当前的Message对象,最后池的数量加1。大致如下图。
假设有来个消息m2,在走一遍同步锁中的代码,此时全局池的状态如下图所示。
其他几个类似
相关文章:
handler解析(4)-Message及Message回收机制
Message中可以携带的信息 Message中可以携带的数据比较丰富,下面对一些常用的数据进行了分析。 /*** 用户定义的消息代码,以便当接受到消息是关于什么的。其中每个Hanler都有自己的命名控件,不用担心会冲突*/ public int what; /*** 如果你…...
Linux使用定时任务监控java进程并拉起
需求描述: 设计一个脚本,通过Linux定时任务,每分钟执行一次,监控jar包进程是否存在,存在则不做动作,不存在则重新拉起jar包程序。 定时任务配置: */1 * * * * bash -x /root/myfile/jars/che…...
Win 10电脑摄像头提示错误代码0xa00f4244怎么办?
如果你的Windows 10电脑无法打开摄像头,提示“我们找不到你的摄像头”的错误消息,错误代码是0xA00F4244,原因可能是杀毒软件阻止了摄像头,或者是摄像头驱动程序有问题。 小编为你整理了摄像头错误代码0xA00F4244的解决方法&#…...
MFC消息机制
1.消息映射消息映射是一个将消息和成员函数相互关联的表。比如,框架窗口接收到一个鼠标左击消息,MFC将搜索该窗口的消息映射,如果存在一个处理WM_LBUTTTONDOWN消息的处理程序,然后就调用OnButtonDown。2.消息映射机制2.1 声明宏 写…...
全国计算机等级考试报名照片要求以及证件照制作教程
马上就全国计算机等级考试就要开始了,相信现在很多同学都在网上进行报名呢,报名的时候肯定需要用到个人证件照片,所以问题来了,我们怎么自己制作证件照片呢?计算机等级考试报名时对证件照都有哪些要求呢?该…...
SQLSERVER 临时表和表变量到底有什么区别?
一:背景 1. 讲故事 今天和大家聊一套面试中经常被问到的高频题,对,就是 临时表 和 表变量 这俩玩意,如果有朋友在面试中回答的不好,可以尝试看下这篇能不能帮你成功迈过。 二:到底有什么区别 1. 前置思…...
技术生态异军突起,昇思MindSpore进入AI框架第一梯队
ChatGPT掀起的新一轮人工智能狂欢下,隐藏在背后的“大模型”正进入越来越多开发者的视野。 诚如几年前开始流行的一种说法:数据是燃料、模型是引擎、算力是加速器。ChatGPT的出现,恰如其分地诠释了数据、模型和算力的“化学反应”。而在其中…...
审批流、工作流、业务流
是业务流、工作流、审批流 业务流:即业务流程,指为了完成某项业务而进行的各种工作的有序组合 工作流:即工作流程,指为了完成某项工作而进行的各种动作的有序组合 审批流:即审批流程,是对某项工作的审批活动…...
如何利用知识库加强内部管理?
许多公司都知道需要有一个面向客户的知识库,以加强客户服务,提供更好的客户体验。 但是很多企业没有意识到的是,拥有一个内部知识库软件对于员工改善沟通和促进知识共享的重要性。 协作是组织成功的关键部分,通过明确的远景和使…...
饕餮 NFT 作品集来袭!
饕餮 NFT 作品集包含 Chili Game 创作的体验《饕餮》第一章中的角色。可以在 The Sandbox 农历新年活动期间(01/18/23 至 02/28/23)体验。 饕餮的故事植根于中国古代神话,主要灵感来自《山海经》,一个关于捉妖人「青蛙侠」的故事。…...
C++中的内存分区、引用、函数
内存分区模型 代码区 存放CPU执行的机器指令代码区是共享的且具有只读性 全局区 全局变量和静态变量都存放在此处全局区还包括了常量区、字符串常量和其他常量也存放在此该区域的数据在程序结束后由操作系统释放const修饰的局部变量并不算在全局区 栈区 由编译器自动分配和释放…...
关于angular表格total模板中一直为0
哈喽 小伙伴们大家好昨天在用angular得antdesign组件得table表格 我用total模板 结果,total一直为0这可是愁坏我了 <ng-template #totalTemplate let-total>找到 {{ total }} 条结果</ng-template>[nzShowTotal]"totalTemplate"最后找到原因了…...
多线程事务怎么回滚
背景介绍1,最近有一个大数据量插入的操作入库的业务场景,需要先做一些其他修改操作,然后在执行插入操作,由于插入数据可能会很多,用到多线程去拆分数据并行处理来提高响应时间,如果有一个线程执行失败&…...
基于FPGA的时间数字转换(TDC)设计(五:基于Carry4的高精度TDC设计)
1.基于Carry4进位链设计原理 常见的基于FPGA开发的TDC有直接计数法,多相位时钟采样法,抽头延迟线法等,之前内容为基于多相位的TDC,本章节中,主要讲解基于抽头延迟线法。在Xilinx FPGA开发中,实现抽头延迟线法有很多种,如使用IODELAY构建延迟进位链,此处将介绍基于Carr…...
【C++】二叉搜索树的实现(递归和非递归实现)
文章目录1、二叉搜索树1.1 构建二叉搜索树1.2 二叉搜索树的插入1.3 二叉搜索树的删除1.4 二叉搜索树插入和删除的递归实现为了学习map和set的底层实现,需要知道红黑树,知道红黑树之前需要知道AVL树。 红黑树和AVL树都用到了二叉搜索树结构,所…...
春招来了,如何正确使用领英超高效招聘海外员工、挖掘人才?
金三银四到了,每年的这个时候都是企业招聘的好时机。而领英是目前全球最大的职场社交网络平台,基本上海外求职都是在使用它,所以很多企业涉及到海外招聘时,都会优先考虑领英,但是却经常缺乏一些经验技巧,今…...
Mysql中锁机制深入理解
Mysql中锁机制深入理解默认大家已经知道。分类性能悲观锁,乐观锁操作类型读锁,写锁,数据粒度表锁,行锁,页面锁更细粒度间隙锁,临键锁按使用来讲。由数据粒度出发。表锁,分为 共享锁,…...
去中心化社交网络协议除了Nostr还有哪些?
当下最火的去中心化社交软件Dmaus就是基于Nostr协议开发的,Nostr协议的基本情况之前的文章《一文了解去中心化社交网络协议Nostr》已经做了详细介绍,本文将介绍其他几个目前比较流行的去中心化社交协议。FarcasterFarcaster是由前Coinbase高管Dan Romero…...
【FT2000/4+X100】调试记录
订阅专栏 硬件环境FT2000/4+X100,单板结构,对外显示,运行银行麒麟操作系统。 一 生成UEFI.BIN,烧写在FT2000-4的QSPI Flash中 1 2 下载源文件 edk2-for-support.tar; 参考文件 ft2004c&D2000编译打包说明V1.0.5; 解压源文件; 根目录下 build2004C.sh为四核产品…...
我的Android启动优化—【黑白屏优化】
简述 在Android App使用过程中,对于应用的优化是一个加分项,举个例子,打开你的App需要2秒,人家0.5秒,这就是很大的用户体验上的优化。 问题的产生 在开发中,我们在启动app的时候,屏幕会出现一…...
TongWeb8编码设置说明
应用场景:在遇到中文问题时,常需要通过设置编码格式来解决问题。下面介绍TongWeb8的编码设置及优先级。一、web.xml中请求、响应编码的配置优先级最高在JavaEE8规范中web.xml增加了request, response编码配置,该配置优先级最高。<?xml ve…...
不同相机之间图片像素对应关系求解(单应性矩阵求解)
一、场景 相机1和相机2相对位置不变,相机拍摄图片有重叠,求他们交叠部分的一一对应关系。数学语言描述为已知相机1图片中P点像素(u1, v1),相机1中P点在相机2图片中像素值为(u2, v2),它们存在某种变换,求变换矩阵。 因为…...
远程管理时代,还得是智能化PDU才靠得住!
在如今这个信息技术高速发展的时代,数据中心IDC机房服务器数量与日俱增,提供DNS域名服务、主机托管服务、虚拟主机服务等服务的服务器是IDC最基本的功能之一。服务器需要7*24小时不间断持续工作,但当服务器数量很大,服务器工作、重…...
通俗易懂理解——布隆过滤器
文章目录概述本质优缺点优点:缺点:实际应用解决redis缓存穿透问题:概述 本质 本质:很长的二进制向量(数组) 主要作用:判断一个数据在这个数组中是否存在,如果不存在为0,…...
TypeScript 学习之类型推导
在一些情况下,代码上没有显性明确类型,typescript 可以隐形推断出类型。 基础 let x 3;变量x的类型被推断为数字。 类型推断发生在初始化变量和成员,设置默认参数值和决定函数返回值时 最佳通用类型 let x [0, 1, null]; // 类型为 numb…...
Android四大组件——Service详解
Service 为后台运行,不可见,没有界面。优先级高于Activity(内存不足时先杀掉Activity),运行在主线程且不能做耗时操作。 一、Service 启动方式 1、startService() 通过 startService 启动后,service会一直…...
svg转png
svg转png写了一个spring boot项目,支持传入svg文件转出png图片,并且自定义转出png的宽和高。主要代码如下:所需依赖如下:演示如下:首先,运行项目使用接口调用工具调用接口发送请求,提取文件1000…...
教你如何搭建人事OA-员工管理系统,demo可分享
1、简介1.1、案例简介本文将介绍,如何搭建人事OA-员工管理。1.2、应用场景人事OA-员工管理应用对员工信息进行管理,可办理入职、转正、离职等流程。2、设置方法2.1、表单搭建1)新建表单【员工管理】,字段设置如下:名称…...
C++递推基础知识
文章目录一、递推的概念二、递推和递归的区别三、递推的实例1、最基础的:斐波那契数列2、变形版斐波那契数列3、较复杂的递推式求解:昆虫繁殖4、经典逆推问题:题目数量一、递推的概念 1、什么是递推算法? 递推算法:是…...
【Python入门第十天】Python 布尔
布尔表示两值之一:True 或 False。 布尔值 在编程中,通常需要知道表达式是 True 还是 False。 可以计算 Python 中的任何表达式,并获得两个答案之一,即 True 或 False。 比较两个值时,将对表达式求值,P…...
番禺厂家关键词优化/seo外推软件
应用程序在运行过程中,会有大量需要处理的异常。在页面解析的一个工程中,会存在多个service类同时出现页面解析异常和解析结果入库异常,而这就表示在程序中需要一个机制,去统一处理这些异常,提供统一的异常处理。因为我…...
云栖建站/seo排名关键词搜索结果
为了让CSR867x的开发更容易,现与思度科技联合推出CSR867x学习板【淘宝链接:思度科技CSR开发板】。 技术交流QQ群号:743434463 开发板会员QQ群号:725398389(凭订单号入群,赠PPT、项目源码、视频教程&#x…...
百度云附件 wordpress/东莞seo外包平台
关于如何架设PT请参考:NexusPHP架设PT服务站点教程 安装完成后发现可以局域网内可以做种,但是外网就不行了,查看种子下载地址列表会显示可连接性为否,查看了announce.php文件,可连接性由这段代码决定 $sockres pfsock…...
页面设计优缺点/北京seo做排名
http://www.brickcom.com/products/DetailView.php?modelnameCMS-Client&seriesCMS#product-support http://ihomeapp.cn/dl_files/CMSClient-manual.pdf转载于:https://www.cnblogs.com/fx2008/p/5999035.html...
wordpress英文主题破解版/互联网营销师含金量
QPushButton 在任何 GUI 设计中,命令按钮都是最重要和最常用的控件。 任何计算机用户都熟悉带有保存、打开、确定、是、否和取消等作为标题的按钮。 在 PyQt API 中,QPushButton 类对象提供了一个按钮,当单击该按钮时,可以对其进行编程以调用某个函数。 QPushButton 类从…...
网站首页做的好看/天津百度快速排名优化
原创不易,转载请注明出处 前言 到目前为止,RocketMQ源码解析博文已经发表了20篇,初步打算是从两个维度来解析RocketMQ的源码,分别是整体运行流程的源码解析,某些核心组件源码深度剖析。现在已经初步完成了RocketMQ核心…...