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输入子系统呢,反 ...
随机推荐
- mybatis与hibernate常用的持久化类,及sqlsession和sqlsessionTemplate区别
首先, 通过翻阅源码,我们来整理一下mybatis进行持久化操作时重要的几个类:SqlSessionFactoryBuilder:build方法创建SqlSessionFactory实例.SqlSes ...
- 51nod 1463 找朋友(线段树+离线处理)
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1463 题意: 思路: 好题! 先对所有查询进行离线处理,按照右区间排序, ...
- blast 数据库说明
Peptide Sequence Databases蛋白序列的数据库 nrAll non-redundant GenBank CDS translations + RefSeq Proteins + ...
- 【NOI2014】动物园
题目链接:http://uoj.ac/problem/5 求:$${\prod _{i=1}^{L}num[i]\%(1e9+7)}$$,${num\left [ i \right ]}$表示:由字符 ...
- Springboot 如何加密,以及利用Swagger2构建Restful API
先看一下使用Swagger2构建Restful API效果图 超级简单的,只需要在pom 中引用如下jar包 <dependency> <groupId>io.springfo ...
- typeof
1.用法 typeof num typeof(num) 2.返回值 "number"."string"."boolean"." ...
- 基于Socket的Android手机视频实时传输
首先,简单介绍一下原理.主要是在手机客户端 (Android)通过实现Camera.PreviewCallback接口,在其onPreviewFrame重载函数里面获取摄像头当前图像数据, 然后通过S ...
- URLConnection和HttpClient使用入门
本讲内容:URLConnection和HttpClient使用入门 在 Android中除了使用WebView控件访问网络以外,还有用代码方式访问网络的方法,代码方式有时候会显得更加灵活.本讲会介绍使 ...
- React生命周期钩子
最近的工作都很忙,所以很少完整的时间可以用来总结和回顾知识点,今天就趁着是周末,我准备在这里复习和回顾一下React的基础.工作中主要用的vue比较多,在工作中使用React也已经是一年前了,当时用的 ...
- Python递归遍历《指定目录》下的所有《文件》
https://www.cnblogs.com/dreamer-fish/p/3820625.html