Android中Parcel的分析以及使用
简单点来说:Parcel就是一个存放读取数据的容器,
Android系统中的binder进程间通信(IPC)就使用了Parcel类来进行客户端与服务端数据的交互,而且AIDL的数据也是通过Parcel来交互的。在Java空间和C++都实现了Parcel,由于它在C/C++中,直接使用了内存来读取数据,因此,它更有效率。
分析Binder机制中的客户端与服务器端进行实际操作ontransact()函数 :
- //参数说明:
- // code :是请求的ID号
- // data :客户端请求发送的参数
- // reply:服务器端返回的结果
- // flags:一些额外的标识,如FLAG_ONEWAY等,通常为0.
- virtual status_t onTransact( uint32_t code,
- );
从中我们可以看到Parcel的重要性以及窥探它的使用情况,接下来,我主要分析它的存储机制。
常用方法介绍:
obtain() 获得一个新的parcel ,相当于new一个对象
dataSize() 得到当前parcel对象的实际存储空间
dataCapacity() 得到当前parcel对象的已分配的存储空间, >=dataSize()值 (以空间换时间)
dataPostion() 获得当前parcel对象的偏移量(类似于文件流指针的偏移量)
setDataPosition()
设置偏移量
recyle() 清空、回收parcel对象的内存
writeInt(int) 写入一个整数
writeFloat(float) 写入一个浮点数
writeDouble(double) 写入一个双精度数
writeString(string) 写入一个字符串
当然,还有更多的writeXXX()方法,与之对应的就是readXXX(),具体方法请参阅SDK。
其中几个值得注意的方法为:
writeException() 在Parcel队头写入一个异常
writeException() Parcel队头写入“无异常“
readException() 在Parcel队头读取,若读取值为异常,则抛出该异常;否则,程序正常运行。
一、Parcel的分析
相信看了前面的值,对Parcel的使用该有了初步印象。那么,Parcel的内部存储机制是怎么样的?偏移量又是
什么情况?让我们回忆一下基本数据类型的取值范围:
boolean 1bit 1字节
char 16bit 2字节
int 32bit 4字节
long 64bit 8字节
float 32bit 4字节
double 64bit 8字节
如果大家对C语言熟悉的话,C语言中结构体的内存对齐和Parcel采用的内存存放机制一样,即读取最小字节
为32bit,也即4个字节。高于4个字节的,以实际数据类型进行存放,但得为4byte的倍数。基本公式如下:
实际存放字节:
判别一: 32bit (<=32bit) 例如:boolean,char,int
判别二: 实际占用字节(>32bit) 例如:long,float,String,数组等
当我们使用readXXX()方法时,读取方法也如上述:
实际读取字节:
判别一: 32bit (<=32bit) 例如:boolean,char,int
判别二: 实际字节大小(>32bit) 例如:long,float,String,数值等
由上可以知道,当我们写入/读取一个数据时,偏移量至少为4byte(32bit),于是,偏移量的公式如下:
f(x)= 4x (x=0,1,…n)
事实上,我们可以显示的通过setDataPostion(int postion) 来直接操作我们欲读取数据时的偏移量。毫无疑问,
你可以设置任何偏移量,但所读取的值是类型可能有误。因此显示设置偏移量读取值的时候,需要小心。
另外一个注意点就是我们在writeXXX()和readXXX()时,导致的偏移量是共用的,例如,我们在writeInt(23)后,
此时的datapostion=4,如果我们想读取5,简单的通过readInt()是不行的,只能得到0。这时我们只能通过
setDataPosition(0)设置为起始偏移量,从起始位置读取四个字节,即23。因此,在读取某个值时,可能需要使用
setDataPostion(int postion)使偏移量装换到我们的值处。
巧用setDataPosition()方法,当我们的parcel对象中只存在某一类型时,我们就可以通过这个方法来快速的读取
所有值。具体方法如下:
- /**
- * 前提条件,Parcel存在多个类型相同的对象,本例子以10个float对象说明:
- */
- public void readSameType() {
- Parcel ; i ; i++) {
- parcel.writeDouble(i);
- Log.i(TAG, "write double ----;
- int datasize = parcel.dataSize();
- while (i < datasize) {
- parcel.setDataPosition(i);
- double fvalue = parcel.readDouble();
- Log.i(TAG, " read double is=" + fvalue + ", --->" + getParcelInfo());
- i += 8; // double占用字节为 8byte
- }
- // 方法二,由于对象的类型一致,我们可以直接利用readXXX()读取值会产生偏移量
- // parcel.setDataPosition(0) ; //
- // while(parcel.dataPosition()<parcel.dataSize()){
- // double fvalue = parcel.readDouble();
- // Log.i(TAG, " read double is=" + fvalue + ", --->" + getParcelInfo());
- // }
- }
由于可能存在读取值的偏差,一个默认的取值规范为:
1、 读取复杂对象时: 对象匹配时,返回当前偏移位置的该对象;
对象不匹配时,返回null对象 ;
2、 读取简单对象时: 对象匹配时,返回当前偏移位置的该对象 ;
对象不匹配时,返回0;
Android中Parcel的分析以及使用的更多相关文章
- Android中AppWidget的分析与应用:AppWidgetProvider .
from: http://blog.csdn.net/thl789/article/details/7887968 本文从开发AppWidgetProvider角度出发,看一个AppWidgetPrv ...
- Android 中图片压缩分析(上)
作者: shawnzhao,QQ音乐技术团队一员 一.前言 在 Android 中进行图片压缩是非常常见的开发场景,主要的压缩方法有两种:其一是质量压缩,其二是下采样压缩. 前者是在不改变图片尺寸的情 ...
- android中SELINUX规则分析和语法简介【转】
本文转载自:https://blog.csdn.net/LoongEmbedded/article/details/62430039 1. SELINUX是可以理解为一种Android上面的安全机制, ...
- android中SELINUX规则分析和语法简介
1. SELINUX是可以理解为一种android上面的安全机制,是有美国国家安全局和一些公司设计的一个针对linux的安全加强系统我们可以通过配置SELINUX的相关policy,来定制自己的手机的 ...
- Android中Touch事件分析--解决HorizontalScrollView滑动和按钮事件触发问题
之前写过关于HorizontalScrollView滑动和按钮事件触发问题,但是不能所有的情况,最近几天一直在想这个问题,今天有一个比较好的解决思路,最终应用在项目里面效果也很好,首先说明一下功能: ...
- Android中应用安装分析
#1 安装方式 1 安装系统APK和预制APK时,通过PMS的构造函数中安装,即第一次开机时安装应用,没有安装界面. 2 网络下载安装,通过应用商店等,即调用PackageManager.instal ...
- Android中Context样式分析
目录 1.样式定义以及使用 1.1.默认样式 1.2.样式定义及使用 1.3.当前样式下attr属性的获取 1.4.属性集合的定义与获取 2.Activity中Theme的初始化流程 2.1.系统调用 ...
- Android中Adapter和Bridge模式理解和应用
一 Adapter模式 意图: 将一个类的接口转换成客户希望的另外一个接口. Adapter模式使得原本由于接口不兼容而不能在一起工作的那些类可以在一起工作. 适用性: 使用一个已存在的类,而它的接口 ...
- Android中Input型输入设备驱动原理分析(一)
转自:http://blog.csdn.net/eilianlau/article/details/6969361 话说Android中Event输入设备驱动原理分析还不如说Linux输入子系统呢,反 ...
随机推荐
- java命令行执行程序解决依赖外部jar包的问题
用java命令行直接执行程序,如果这个程序需要引用外部jar包.就不能单纯用java xx来执行 如果你的jar包和程序就在一个目录: 编译 javac -cp D:\yy\yy.jar,D\xx\x ...
- Hibernate五大核心接口简介
所有的Hibernate应用中都会访问Hibernate的5个核心接口. Configuration接口:配置Hibernate,根启动Hibernate,创建SessionFactory对象. Se ...
- Springboot mybatis generate 自动生成实体类和Mapper
https://github.com/JasmineQian/SpringDemo_2019/tree/master/mybatis Springboot让java开发变得方便,Springboot中 ...
- Qt5_自定义处理Windows消息函数
ZC:(1).“#include <QAbstractNativeEventFilter>”,(2).貌似 返回True(意思是 处理过了) 返回False(意思是还需要继续处理) 1.参 ...
- 如何学习编程和做好DBA
关于学习编程和做好DBA的关系 我这里只是讨论SQLSERVER DBA 我发现很多DBA都是从程序员开始做起的,一般做了4.5年之后就转型做DBA或者管理或者销售啊. 为什麽一开始不直接做DBA,D ...
- java.lang.NoSuchMethodError问题处理
出现这个问题一般是jar包冲突了,我找了很久没找到是哪个jar冲突了.最后用下面的这段代码,找到是哪个jar冲突了 /** * find jar file */ String LOCATION = & ...
- 构建NCBI本地BLAST数据库 (NR NT等) | blastx/diamond使用方法 | blast构建索引 | makeblastdb
参考链接: FTP README 如何下载 NCBI NR NT数据库? 下载blast:ftp://ftp.ncbi.nlm.nih.gov/blast/executables/blast+ 先了解 ...
- WPF自定义控件的两种方式
方法A: 第一步:My自定义控件:Control 第二步:针对 “My自定义控件” 类型,编写<style>或<模板>(UI的外观完全由用户自己定义) 第三步: 使用My自定 ...
- 新概念 Lesson 3 Nice to meet you
Nice to meet you. 你好 打招呼: hi,hello 重点: 打招呼和互相介绍.主系表结构 Is Chang-woo Chinese? 昌武是中国人吗? No,he isn't . H ...
- Professional layer CodeForces - 1103D (状压,gcd)
大意: 给定$n$元素序列$a$, 现在想要让$gcd(a_1,a_2,...,a_n)=1$. 对于每个$a_i$可以除以一个不超过$k$的因子, 代价为$e_i$, 假设一共选择了$x$个元素去除 ...