天天看點

Android Parcelable和Serializable差別

本文主要介紹Parcelable和Serializable的作用、效率、差別及選擇

1、作用

Serializable的作用是為了儲存對象的屬性到本地檔案、資料庫、網絡流、rmi以友善資料傳輸,當然這種傳輸可以是程式内的也可以是兩個程式間的。而Android的Parcelable的設計初衷是因為Serializable效率過慢,為了在程式内不同元件間以及不同Android程式間(AIDL)高效的傳輸資料而設計,這些資料僅在記憶體中存在,Parcelable是通過IBinder通信的消息的載體。

從上面的設計上我們就可以看出優劣了。

2、效率及選擇

Parcelable的性能比Serializable好,在記憶體開銷方面較小,是以在記憶體間資料傳輸時推薦使用Parcelable,如activity間傳輸資料,而Serializable可将資料持久化友善儲存,是以在需要儲存或網絡傳輸資料時選擇Serializable,因為android不同版本Parcelable可能不同,是以不推薦使用Parcelable進行資料持久化

3、程式設計實作

對于Serializable,類隻需要實作Serializable接口,并提供一個序列化版本id(serialVersionUID)即可。而Parcelable則需要實作writeToParcel、describeContents函數以及靜态的CREATOR變量,實際上就是将如何打包和解包的工作自己來定義,而序列化的這些操作完全由底層實作。

Parcelable的一個實作例子如下

[java]  view plain  copy

  1. public class MyParcelable implements Parcelable {  
  2.      private int mData;  
  3.      private String mStr;  
  4.      public int describeContents() {  
  5.          return 0;  
  6.      }  
  7.      // 寫資料進行儲存  
  8.      public void writeToParcel(Parcel out, int flags) {  
  9.          out.writeInt(mData);  
  10.          out.writeString(mStr);  
  11.      }  
  12.      // 用來建立自定義的Parcelable的對象  
  13.      public static final Parcelable.Creator<MyParcelable> CREATOR  
  14.              = new Parcelable.Creator<MyParcelable>() {  
  15.          public MyParcelable createFromParcel(Parcel in) {  
  16.              return new MyParcelable(in);  
  17.          }  
  18.          public MyParcelable[] newArray(int size) {  
  19.              return new MyParcelable[size];  
  20.          }  
  21.      };  
  22.      // 讀資料進行恢複  
  23.      private MyParcelable(Parcel in) {  
  24.          mData = in.readInt();  
  25.          mStr = in.readString();  
  26.      }  
  27.  }  

從上面我們可以看出Parcel的寫入和讀出順序是一緻的。如果元素是list讀出時需要先new一個ArrayList傳入,否則會報空指針異常。如下:

list = new ArrayList<String>();
in.readStringList(list);      

 PS: 在自己使用時,read資料時誤将前面int資料當作long讀出,結果後面的順序錯亂,報如下異常,當類字段較多時務必保持寫入和讀取的類型及順序一緻。

11-21 20:14:10.317: E/AndroidRuntime(21114): Caused by: java.lang.RuntimeException: Parcel [email protected]: Unmarshalling unknown type code 3014773 at offset 164      

4、進階功能上

Serializable序列化不儲存靜态變量,可以使用Transient關鍵字對部分字段不進行序列化,也可以覆寫writeObject、readObject方法以實作序列化過程自定義