我是靠谱客的博主 风中音响,最近开发中收集的这篇文章主要介绍android parcel.cpp 函数指针,Parcel_进程间数据传递,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

Parcel,即打包。为何须要打包呢?是为了序列化。java

若是要在进程之间传递一个整数,很简单,直接传就好了;若是要传一个字符串,就稍微复杂了点:需先分配一块能够容纳字符串的内存,而后将字符串复制到内存中,再传递(新手可能问:为啥不直接把字符串的引用传过去呢?学过C/C++的地球人都知道:进程有本身的内存地址空间,一个进程中的1000地址可能在另外一个进程中是100000,Java对象的引用跟本上仍是内存地址);再若是要传递一个类的实例呢?也是先为实例分配内存,而后复制一份再传递能够吗?我认为不能够,我至少能够找到一个理由:类中成员除了属性还有方法,即便属性能完整传过去,但方法呢?方法是独立于类对象存在的,因此到另外一个进程中再引用同一个方法就要出错了,仍是由于独立地址空间的缘由。android

Android开发中,常常在Activity之间传递数据,而根据android的设计架构,即便同一个应用程序中的Activity都不必定运行在同一个进程中,因此处理数据传递时你不能假设两个Activity都运行于同一进程中,那么只能按进程间传递数据来处理,使之具备最普遍的适应性。服务器

如何在进程之间传递类对象呢?简单来讲能够这样作:在进程A中把类中的非默认值的属性和类的惟一标志打成包(这就叫序列化),把这个包传递到进程B,进程B接收到包后,根据类的惟一标志把类建立出来,而后把传来的属性更新到类对象中,这样进程A和进程B中就包含了两个彻底同样的类对象。架构

Parcel就是一个存放读取数据的容器, Android系统中的binder进程间通讯(IPC)就使用了Parcel类来进行客户端与服务端数据的交互,并且AIDL的数据也是经过Parcel来交互的。在Java空间和C++都实现了Parcel,因为它在C/C++中,直接使用了内存来读取数据,所以,它更有效率。

ide

分析Binder机制中的客户端与服务器端进行实际操做onTransact()函数 :函数

// code :是请求的ID号

// data :客户端请求发送的参数

// reply:服务器端返回的结果

// flags:一些额外的标识,如FLAG_ONEWAY等,一般为0.

virtualstatus_t    onTransact( uint32_t code,constParcel& data,   Parcel* reply,   uint32_t flags = 0);

从中咱们能够看到Parcel的重要性。post

经常使用方法介绍:性能

obtain()                          得到一个新的parcel ,至关于new一个对象网站

dataSize()                      获得当前parcel对象的实际存储空间ui

dataCapacity()               获得当前parcel对象的已分配的存储空间, >=dataSize()值  (以空间换时间)

dataPosition()                 得到当前parcel对象的偏移量(相似于文件流指针的偏移量)

setDataPosition()           设置偏移量

recycle()                           清空、回收parcel对象的内存

writeInt(int)                     写入一个整数

writeFloat(float)              写入一个浮点数

writeDouble(double)       写入一个双精度数

writeString(string)           写入一个字符串

固然,还有更多的writeXXX()方法,与之对应的就是readXXX()。

事实上,咱们能够显式的经过setDataPostion(int postion) 来直接操做咱们欲读取数据时的偏移量。毫无疑问,你能够设置任何偏移量,但所读取的值是类型可能有误。所以显示设置偏移量读取值的时候,须要当心。

另一个注意点就是咱们在writeXXX()和readXXX()时,致使的偏移量是共用的,例如,咱们在writeInt(23)后,

此时的datapostion=4,若是咱们想读取23,简单的经过readInt()是不行的,只能获得0。这时咱们只能经过

setDataPosition(0)设置为起始偏移量,从起始位置读取四个字节,即23。所以,在读取某个值时,可能须要使用

setDataPostion(int postion)使偏移量装换到咱们的值处。

巧用setDataPosition()方法,当咱们的Parcel对象中只存在某一类型时,咱们就能够经过这个方法来快速的读取

全部值。具体方法以下:

/**

* 前提条件,Parcel存在多个类型相同的对象,本例子以10个float对象说明:

*/

publicvoidreadSameType() {

Parcel parcel =Parcel.obtain() ;

for(inti =0; i <10; i++) {

parcel.writeDouble(i);

Log.i(TAG, "write double ----> "+ getParcelInfo());

}

//方法一 ,显式设置偏移量

inti =0;

intdatasize = parcel.dataSize();

while(i 

parcel.setDataPosition(i);

doublefvalue = parcel.readDouble();

Log.i(TAG, " read double is="+ fvalue +", --->"+ getParcelInfo());

i += 8;// double占用字节为 8byte

}

//      方法二,因为对象的类型一致,咱们能够直接利用readXXX()读取值会产生偏移量

//      parcel.setDataPosition(0)  ;  //

//      while(parcel.dataPosition()

//          double fvalue = parcel.readDouble();

//          Log.i(TAG, " read double is=" + fvalue + ", --->" + getParcelInfo());

//      }

}

因为可能存在读取值的误差,一个默认的取值规范为:

一、  读取复杂对象时: 对象匹配时,返回当前偏移位置的该对象;  对象不匹配时,返回null对象 ;

二、  读取简单对象时: 对象匹配时,返回当前偏移位置的该对象 ; 对象不匹配时,返回0;

最后

以上就是风中音响为你收集整理的android parcel.cpp 函数指针,Parcel_进程间数据传递的全部内容,希望文章能够帮你解决android parcel.cpp 函数指针,Parcel_进程间数据传递所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(44)

评论列表共有 0 条评论

立即
投稿
返回
顶部