序列化數據原理:
序列化的過程就是對象寫入字節流和從字節流中讀取對象。將對象狀態轉換成字節流之後,可以用java.io包中的各種字節流類將其保存到文件中,管道到另一線程中或通過網絡連接將對象數據發送到另一主機。
簡單說就是將數據對象存入字節流當中,在需要時重新生成對象。
Android中的序列化機制:
首先android系統利用Binder進行IPC通訊,且定位為針對內存受限的設備,所以則要求使用高效的對象傳輸方式,因為Parcel應運而生。
代碼分析:
frameworks\base\core\java\android\os\Parcel.java
frameworks\base\core\jni\android_util_Binder.cpp JNI函數
以典型代碼片段舉例:
- /**
- * Write an integer value into the parcel at the current dataPosition(),
- * growing dataCapacity() if needed.
- */
- public final native void writeInt(int val);
-
-
- /**
- * Write a long integer value into the parcel at the current dataPosition(),
- * growing dataCapacity() if needed.
- */
- public final native void writeLong(long val);
-
-
- /**
- * Write a floating point value into the parcel at the current
- * dataPosition(), growing dataCapacity() if needed.
- */
- public final native void writeFloat(float val);
JNI層實現:
- 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 void android_os_Parcel_writeLong(JNIEnv* env, jobject clazz, jlong val)
- {
- Parcel* parcel = parcelForJavaObject(env, clazz);
- if (parcel != NULL) {
- const status_t err = parcel->writeInt64(val);
- if (err != NO_ERROR) {
- jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
- }
- }
- }
-
-
- static void android_os_Parcel_writeFloat(JNIEnv* env, jobject clazz, jfloat val)
- {
- Parcel* parcel = parcelForJavaObject(env, clazz);
- if (parcel != NULL) {
- const status_t err = parcel->writeFloat(val);
- if (err != NO_ERROR) {
- jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
- }
- }
- }
其本質使用 Parcel 對象來完成的,實現代碼在:frameworks/base/libs/binder/parcel.cpp
- 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::growData(size_t len)
- {
- size_t newSize = ((mDataSize+len)*3)/2; // 每次多分配50%的內存空間
- return (newSize <= mDataSize)
- ? (status_t) NO_MEMORY
- : continueWrite(newSize);
- }