Message 在Android中主要是在 消息循环机制 中使用,即配合 Handler,LooperMessageQueue来进行线程切换,线程间传递数据。Message存储了我们所有需要的东西。

还可以配合Handler在IPC中传递数据。

我们在使用的过程中应该使用obtain()这个方法来重复利用消息池里面的Message

而复用池本质上就是一个单向链表,为了更好的理解,Message复用池的实现,我们先来看下,简单的单向链表实现.

public final class Message implements Parcelable {
...
// 下一个节点的引用
Message next;
// 这里起到类锁的功能,相当于 Message.class
private static final Object sPoolSync = new Object();
// 可以类比为 头结点
private static Message sPool;
// 链表的长度
private static int sPoolSize = 0;
// 链表的最大长度
private static final int MAX_POOL_SIZE = 50;
// 获取Message对象,类比单向链表的removeHead操作
public static Message obtain() {
// 同步锁, 这里相当于锁住 Message.class, 起到类锁的作用, 每一个Message实例都是同一把锁
synchronized (sPoolSync) {
// 链表中有可复用的Message,直接拿到头结点,然后将头结点指向下一个元素
if (sPool != null) {
Message m = sPool;
sPool = m.next;
m.next = null;
m.flags = 0; // clear in-use flag
sPoolSize--;
return m;
}
}
// 链表中,没有可复用的message,直接new
return new Message();
}
// 类比单向链表的insertHead操作
void recycleUnchecked() {
// 清空数据操作
obj = null;
...
// 同步锁
synchronized (sPoolSync) {
// 如果链表长度小于50,将当前结点,加入链表头部
if (sPoolSize < MAX_POOL_SIZE) {
next = sPool;
sPool = this;
sPoolSize++;
}
}
}
...
}

从上面的分析,我们来梳理一下整体的流程思想.

  • Message 使用一个静态变量,来起到头结点的作用.

静态变量属于类变量,内存中只会存在一份引用,正好能起到 头结点的作用

  • Message 将自身作为Node节点,存储下一个节点的引用,和自身数据
  • obtain()方法相当于链表中移除首元素,并返回该元素的操作

从复用池中获取Message避免了 new创建的消耗.

  • recycleUnchecked()方法相当于链表中将节点加入到头部的操作

添加到复用池之前,会先将Message中的数据清空.

  • Message添加了线程安全的操作
  • Message复用池最多保存50个使用完待复用的Message

50个可能是考虑到内存开销和时间开销的平衡, 不是将数据无限制的添加到复用池.


Message将自身作为节点, 使用一个静态变量作为头结点,让Message自身形成一个链表,而链表中存的是 已经清空数据的Message对象, 以这种方式起到复用的效果!


Message源码分析的更多相关文章

  1. Android Handler机制(一)---Message源码分析

    Message: 定义: public final class Message implements Parcelable Message类是个final类,就是说不能被继承,同时Message类实现 ...

  2. Android Handler处理机制 ( 一 )(图+源码分析)——Handler,Message,Looper,MessageQueue

    android的消息处理机制(图+源码分析)——Looper,Handler,Message 作为一个大三的预备程序员,我学习android的一大乐趣是可以通过源码学习 google大牛们的设计思想. ...

  3. RocketMQ 源码分析 —— Message 发送与接收

    1.概述 Producer 发送消息.主要是同步发送消息源码,涉及到 异步/Oneway发送消息,事务消息会跳过. Broker 接收消息.(存储消息在<RocketMQ 源码分析 —— Mes ...

  4. zookeeper源码分析之五服务端(集群leader)处理请求流程

    leader的实现类为LeaderZooKeeperServer,它间接继承自标准ZookeeperServer.它规定了请求到达leader时需要经历的路径: PrepRequestProcesso ...

  5. java使用websocket,并且获取HttpSession,源码分析

    转载请在页首注明作者与出处 http://www.cnblogs.com/zhuxiaojie/p/6238826.html 一:本文使用范围 此文不仅仅局限于spring boot,普通的sprin ...

  6. ABP源码分析四十二:ZERO的身份认证

    ABP Zero模块通过自定义实现Asp.Net Identity完成身份认证功能, 对Asp.Net Identity做了较大幅度的扩展.同时重写了ABP核心模块中的permission功能,以实现 ...

  7. MyCat源码分析系列之——前后端验证

    更多MyCat源码分析,请戳MyCat源码分析系列 MyCat前端验证 MyCat的前端验证指的是应用连接MyCat时进行的用户验证过程,如使用MySQL客户端时,$ mysql -uroot -pr ...

  8. gRPC源码分析0-导读

    gRPC是Google开源的新一代RPC框架,官网是http://www.grpc.io.正式发布于2016年8月,技术栈非常的新,基于HTTP/2,netty4.1,proto3.虽然目前在工程化方 ...

  9. 移动web app开发必备 - Deferred 源码分析

    姊妹篇  移动web app开发必备 - 异步队列 Deferred 在分析Deferred之前我觉得还是有必要把老套的设计模式给搬出来,便于理解源码! 观察者模式 观察者模式( 又叫发布者-订阅者模 ...

  10. jQuery-1.9.1源码分析系列(十六)ajax——响应数据处理和api整理

    ajax在得到请求响应后主要会做两个处理:获取响应数据和使用类型转化器转化数据 a.获取响应数据 获取响应数据是调用ajaxHandleResponses函数来处理. ajaxHandleRespon ...

随机推荐

  1. 关于FPGA学习的疑惑

    记录心路历程--第一次真正意义上的找工作. 最近在学习小梅哥的FPGA的过程中,总是学习着前面的东西忘着后面的,进行了过一次复习,我准备是在每个章节学完之后,再复习之前的章节,可这样是真的很耗费时间. ...

  2. 2html5

    多媒体标签 <audio> <audio src='../audio/bxb.mp3' controls="controls" autoplay="au ...

  3. linux下opencv contrib安装

    opencv安装 1.1 安装依赖 sudo apt-get update sudo apt-get install build-essential sudo apt-get install cmak ...

  4. 微信小程序地理定位和城市选择列表

    1.先获取用户是否授权地理定位,如果没有让其跳转到设置页面手动开启(获取到的位置是经纬度,需要借助其他地图SDK的地址逆解析获取省市区的名字) getSetting() { wx.getSetting ...

  5. 使用hugo在gitee上写blog

    1. 安装hugo 1)下载 Hugo Releases,选择hugo_xxx_Windows-64bit.zip(xxx位版本). 2)设置路径 我的电脑->属性->高级系统设置-> ...

  6. 从XXE漏洞修复引起Not supported: http://javax.xml.XMLConstants/property/accessExternalDTD说到SPI机制

    引子  在使用Fortify扫描时代码报XML External Entity Injection,此漏洞为xml实体注入漏洞,XXE攻击可利用在处理时动态构建文档的 XML 功能.修复方案也包含了增 ...

  7. 转发:基于Lerna打造多包管理最佳实践之道

    最近在看vue-cli的源码部分,注意到这一个仓库下维护了多个package,很好奇他是如何在一个repo中管理这些package的. 我们组现在也在使用组件库的方式维护项目间共用的业务代码.有两个组 ...

  8. Unity检测鼠标是否与UI交互

    在Unity项目中,假设在鼠标按键时会触发游戏内的操作,但是在鼠标与UI进行交互时我们希望停止游戏中的操作,这是需要使用EventSystem中的方法来检测鼠标是否正在与UI交互 private bo ...

  9. Fastboot_Cmd

    /* -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- */adb命令:/* -*-* ...

  10. 手写一个简易的ajax

    function ajax(url,successFul){ const xhr=new XMLHttpRequest() xhr.open("Get",url,true) xhr ...