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<Gril> CREATOR = new Parcelable.Creator<Gril>() { 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<class T> 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<T*>(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<class T> 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<const T*>(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<ClassName> arrayList = new ArrayList<ClassName>(); for (Parcelable object : parcelableArr) { arrayList.add((ClassName)object); }
2014-07-24 新增疑问
2014-12-31 新增序列与反序列化例子,疑问放入《Java 序列化简单理解,serializable与externalizable区别?》