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. }     
  • 1
  • 2
  • 下一页

相关内容