转自:http://hi.baidu.com/mcu99/blog/item/5a8f5b01b105cede267fb54f.html
Android中的Parcel类困惑了我好一段时间(当然现在也没把Parcel完全弄明白),查了一些资料也不知道它里面是以一种什么格式存储数据的。因为它对外提供的读写函数都没有提到具体一个读写函数到底是读写Parcel中的哪一块地址里的数据。比如网上有这么两段代码: public void writeToParcel(Parcel out) { //当前数据写入到Parcel中 out.writeInt(left); out.writeInt(top); out.writeInt(right); out.writeInt(bottom); } public void readFromParcel(Parcel in) { //从Parcel中读取数据 left = in.readInt(); top = in.readInt(); right = in.readInt(); bottom = in.readInt(); } 其中无论是读函数writeInt(),还是写函数readInt(),参数中都没有提及是往Parcel中的具体哪块地方写入left变量,又是从Parcel的哪块地方读出数值赋给right变量。后来看了一些源码,包括Parcel.h和Parcel.cpp。感觉Parcel可能类似一个一维的数据串,各种变量都可以往里面写(通过Parcel提供的针对各种变量的具体函数),有一个位置指针指向这个一维的数据串中的某个位置,这个位置就是默认的读写的位置。也就是说,如果现在调用读写函数,就是读写当前位置指针处的数据,读写结束后,把位置指针向后移动一块空间(跨越的长度正好是你上次调用读写函数读过或者写过数据的长度),继续准备对下一部分空间进行读写操作。为了验证这个想法,编写了一段对Parcel进行读写的C++程序。由于对C++较为生疏,编写这个小程序花了一下午的时间,不过最后总算是通过了。现在把代码贴在下面:
parcel_test.cpp文件:
#include <binder/Parcel.h> #include <stdio.h> #include <stdlib.h> int main() { using namespace android; status_t status; size_t parcel_position; int32_t intp=987654; char charp='g'; float floatp=3.14159; double doublep=12345.6789012; long longp=1234567890; char *stringp="this is my parcel test!"; Parcel p; parcel_position = p.dataPosition(); /*备份位置*/ printf("当前Parcel的读写位置是:%d/n", parcel_position); status = p.writeInt32(intp); if (status==NO_ERROR) printf("write int type success!/n"); else printf("write int type fail,the errno=%d/n",errno); status=p.writeInt32(charp); if (status==NO_ERROR) printf("write char type success!/n"); else printf("write char type fail,the errno=%d/n",errno); status=p.writeFloat(floatp); if (status==NO_ERROR) printf("write Float type success!/n"); else printf("write Float type fail,the errno=%d/n",errno); status=p.writeDouble(doublep); if (status==NO_ERROR) printf("write Double type success!/n"); else printf("write Double type fail,the errno=%d/n",errno); status=p.writeInt64(longp); if (status==NO_ERROR) printf("write long type success!/n"); else printf("write long type fail,the errno=%d/n",errno); status=p.writeCString(stringp); if (status==NO_ERROR) printf("write String type success!/n"); else printf("write String type fail,the errno=%d/n",errno); //将parcel读写位置置回原位 p.setDataPosition(parcel_position); //读出变量 printf("读出的int类型变量为:%d/n",p.readInt32()); printf("读出的char类型变量为:%c/n",(char)p.readInt32()); printf("读出的Float类型变量为:%f/n",(float)p.readFloat()); printf("读出的Double类型变量为:%f/n",(double)p.readDouble()); printf("读出的long类型变量为:%ld/n",(long)p.readInt64()); printf("读出的字符串为:%s/n",p.readCString()); }
Android.mk文件:
LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES:= / parcel_test.cpp / LOCAL_SHARED_LIBRARIES := / libbinder / LOCAL_MODULE:= parcel_test include $(BUILD_EXECUTABLE) #include $(call all-makefiles-under,$(LOCAL_PATH))
