歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Android教程:Parcelable 序列化操作數據

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

日期:2017/3/1 10:18:35   编辑:Linux編程

序列化數據原理:
序列化的過程就是對象寫入字節流和從字節流中讀取對象。將對象狀態轉換成字節流之後,可以用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. * Write a long integer value into the parcel at the current dataPosition(),
  8. * growing dataCapacity() if needed.
  9. */
  10. public final native void writeLong(long val);
  11. /**
  12. * Write a floating point value into the parcel at the current
  13. * dataPosition(), growing dataCapacity() if needed.
  14. */
  15. 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. static void android_os_Parcel_writeLong(JNIEnv* env, jobject clazz, jlong val)
  12. {
  13. Parcel* parcel = parcelForJavaObject(env, clazz);
  14. if (parcel != NULL) {
  15. const status_t err = parcel->writeInt64(val);
  16. if (err != NO_ERROR) {
  17. jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
  18. }
  19. }
  20. }
  21. static void android_os_Parcel_writeFloat(JNIEnv* env, jobject clazz, jfloat val)
  22. {
  23. Parcel* parcel = parcelForJavaObject(env, clazz);
  24. if (parcel != NULL) {
  25. const status_t err = parcel->writeFloat(val);
  26. if (err != NO_ERROR) {
  27. jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
  28. }
  29. }
  30. }

其本質使用 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. if ((mDataPos+sizeof(val)) <= mDataCapacity) {
  10. restart_write:
  11. *reinterpret_cast<T*>(mData+mDataPos) = val; // 直接在此將數據寫入到內存中
  12. return finishWrite(sizeof(val));
  13. }
  14. status_t err = growData(sizeof(val)); // 數據空間不夠的情況下處理
  15. if (err == NO_ERROR) goto restart_write;
  16. return err;
  17. }
  18. status_t Parcel::growData(size_t len)
  19. {
  20. size_t newSize = ((mDataSize+len)*3)/2; // 每次多分配50%的內存空間
  21. return (newSize <= mDataSize)
  22. ? (status_t) NO_MEMORY
  23. : continueWrite(newSize);
  24. }
Copyright © Linux教程網 All Rights Reserved