public class Gril implements Parcelable {
private int mAge; // 年龄
private boolean mSexy; // 是否性感
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mAge);
dest.writeByte((byte) (mSexy ? 1 : 0));
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public Gril createFromParcel(Parcel in) {
Gril gril = new Gril();
gril.mAge = in.readInt();
gril.mSexy = in.readByte() != 0;
return gril;
}
public Gril[] newArray(int size) {
return new Gril[size];
}
};
@Override
public int describeContents() {
return 0;
}
}
从上面的例子中可以看出,具体的写入(dest.writeInt(mAge);)与读取(gril.mAge = in.readInt();)都是针对Parcel对象进行的操作,下面贴出的是Parcle 读写int类型数据的定义。
public final class Parcel {
......
/**
* Write an integer value into the parcel at the current dataPosition(),
* growing dataCapacity() if needed.
*/
public final native void writeInt(int val);
/**
* Read an integer value from the parcel at the current dataPosition().
*/
public final native int readInt();
......
}
static void android_os_Parcel_writeInt(JNIEnv* env, jobject clazz, jint val)
{
Parcel* parcel = parcelForJavaObject(env, clazz);
if (parcel != NULL) {
const status_t err = parcel->writeInt32(val);
if (err != NO_ERROR) {
jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
}
}
}
static jint android_os_Parcel_readInt(JNIEnv* env, jobject clazz)
{
Parcel* parcel = parcelForJavaObject(env, clazz);
if (parcel != NULL) {
return parcel->readInt32();
}
return 0;
}
status_t Parcel::writeInt32(int32_t val)
{
return writeAligned(val);
}
template
status_t Parcel::writeAligned(T val) {
COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE(sizeof(T)) == sizeof(T));
if ((mDataPos+sizeof(val)) <= mDataCapacity) {
restart_write:
*reinterpret_cast(mData+mDataPos) = val;
return finishWrite(sizeof(val));
}
status_t err = growData(sizeof(val));
if (err == NO_ERROR) goto restart_write;
return err;
}
status_t Parcel::readInt32(int32_t *pArg) const
{
return readAligned(pArg);
}
template
status_t Parcel::readAligned(T *pArg) const {
COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE(sizeof(T)) == sizeof(T));
if ((mDataPos+sizeof(T)) <= mDataSize) {
const void* data = mData+mDataPos;
mDataPos += sizeof(T);
*pArg = *reinterpret_cast(data);
return NO_ERROR;
} else {
return NOT_ENOUGH_DATA;
}
}
4. 对于普通数据,使用的是mData内存地址,对于IBinder类型的数据以及FileDescriptor使用的是mObjects内存地址。后者是通过flatten_binder()和unflatten_binder()实现的,目的是反序列化时读出的对象就是原对象而不用重新new一个新对象。
dest.writeParcelableArray(mClassNameList.toArray(new ClassName[mClassNameList.size()]), flags);
Parcelable[] parcelableArr = in.readParcelableArray(ClassName.class.getClassLoader());
ArrayList arrayList = new ArrayList();
for (Parcelable object : parcelableArr) {
arrayList.add((ClassName)object);
}
2014-07-24 新增疑问
2014-12-31 新增序列与反序列化例子,疑问放入《Java 序列化简单理解,serializable与externalizable区别?》