歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Android教程:Parcelable 序列化操作數據

序列化數據原理:
序列化的過程就是對象寫入字節流和從字節流中讀取對象。將對象狀態轉換成字節流之後,可以用java.io包中的各種字節流類將其保存到文件中,管道到另一線程中或通過網絡連接將對象數據發送到另一主機。
簡單說就是將數據對象存入字節流當中,在需要時重新生成對象。

Android中的序列化機制:
首先android系統利用Binder進行IPC通訊,且定位為針對內存受限的設備,所以則要求使用高效的對象傳輸方式,因為Parcel應運而生。

代碼分析:
frameworks\base\core\java\android\os\Parcel.java
frameworks\base\core\jni\android_util_Binder.cpp JNI函數

以典型代碼片段舉例:

  1. /** 
  2.  * Write an integer value into the parcel at the current dataPosition(), 
  3.  * growing dataCapacity() if needed. 
  4.  */  
  5. public final native void writeInt(int val);  
  6.   
  7.   
  8. /** 
  9.  * Write a long integer value into the parcel at the current dataPosition(), 
  10.  * growing dataCapacity() if needed. 
  11.  */  
  12. public final native void writeLong(long val);  
  13.   
  14.   
  15. /** 
  16.  * Write a floating point value into the parcel at the current 
  17.  * dataPosition(), growing dataCapacity() if needed. 
  18.  */  
  19. public final native void writeFloat(float val);  

JNI層實現:

  1. static void android_os_Parcel_writeInt(JNIEnv* env, jobject clazz, jint val)  
  2. {  
  3.     Parcel* parcel = parcelForJavaObject(env, clazz);  
  4.     if (parcel != NULL) {  
  5.         const status_t err = parcel->writeInt32(val);  
  6.         if (err != NO_ERROR) {  
  7.             jniThrowException(env, "java/lang/OutOfMemoryError", NULL);  
  8.         }  
  9.     }  
  10. }  
  11.   
  12.   
  13. static void android_os_Parcel_writeLong(JNIEnv* env, jobject clazz, jlong val)  
  14. {  
  15.     Parcel* parcel = parcelForJavaObject(env, clazz);  
  16.     if (parcel != NULL) {  
  17.         const status_t err = parcel->writeInt64(val);  
  18.         if (err != NO_ERROR) {  
  19.             jniThrowException(env, "java/lang/OutOfMemoryError", NULL);  
  20.         }  
  21.     }  
  22. }  
  23.   
  24.   
  25. static void android_os_Parcel_writeFloat(JNIEnv* env, jobject clazz, jfloat val)  
  26. {  
  27.     Parcel* parcel = parcelForJavaObject(env, clazz);  
  28.     if (parcel != NULL) {  
  29.         const status_t err = parcel->writeFloat(val);  
  30.         if (err != NO_ERROR) {  
  31.             jniThrowException(env, "java/lang/OutOfMemoryError", NULL);  
  32.         }  
  33.     }  
  34. }  

其本質使用 Parcel 對象來完成的,實現代碼在:frameworks/base/libs/binder/parcel.cpp

  1. status_t Parcel::writeInt32(int32_t val)  
  2. {  
  3.     return writeAligned(val);  
  4. }  
  5. --> 直接利用模塊實現   
  6. template<class T>  
  7. status_t Parcel::writeAligned(T val) {  
  8.     COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE(sizeof(T)) == sizeof(T));  
  9.   
  10.     if ((mDataPos+sizeof(val)) <= mDataCapacity) {  
  11. restart_write:  
  12.         *reinterpret_cast<T*>(mData+mDataPos) = val; // 直接在此將數據寫入到內存中   
  13.         return finishWrite(sizeof(val));  
  14.     }  
  15.   
  16.     status_t err = growData(sizeof(val)); // 數據空間不夠的情況下處理   
  17.     if (err == NO_ERROR) goto restart_write;  
  18.     return err;  
  19. }  
  20.   
  21. status_t Parcel::growData(size_t len)  
  22. {  
  23.     size_t newSize = ((mDataSize+len)*3)/2;  // 每次多分配50%的內存空間   
  24.     return (newSize <= mDataSize)  
  25.             ? (status_t) NO_MEMORY  
  26.             : continueWrite(newSize);  
  27. }     
Copyright © Linux教程網 All Rights Reserved