java.io.Serializable
android.os.Parcelable
本文主要介绍Parcelable和Serializable的作用、效率、区别及选择,关于Serializable的介绍见Java 序列化的高级认识。
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的一个实现例子如下
package com.pkfeast.bean; import org.codehaus.jackson.annotate.JsonProperty; import android.os.Parcel; import android.os.Parcelable; public class PkImageData implements Parcelable{ @JsonProperty private int PKID; @JsonProperty private String Name; @JsonProperty private String Logo; @JsonProperty private int SenderID; @JsonProperty private int VisitNum; @JsonProperty private int TotalVisitNum; public PkImageData() { super(); } public PkImageData(int pKID, String name, String logo, int senderID, int visitNum, int totalVisitNum) { super(); PKID = pKID; Name = name; Logo = logo; SenderID = senderID; VisitNum = visitNum; TotalVisitNum = totalVisitNum; } public int getPKID() { return PKID; } public void setPKID(int pKID) { PKID = pKID; } public String getName() { return Name; } public void setName(String name) { Name = name; } public String getLogo() { return Logo; } public void setLogo(String logo) { Logo = logo; } public int getVisitNum() { return VisitNum; } public void setVisitNum(int visitNum) { VisitNum = visitNum; } public int getSenderID() { return SenderID; } public void setSenderID(int senderID) { SenderID = senderID; } public int getTotalVisitNum() { return TotalVisitNum; } public void setTotalVisitNum(int totalVisitNum) { TotalVisitNum = totalVisitNum; } @Override public String toString() { return "PkImageData [PKID=" + PKID + ", Name=" + Name + ", Logo=" + Logo + ", SenderID=" + SenderID + ", VisitNum=" + VisitNum + ", TotalVisitNum=" + TotalVisitNum + "]"; } public static final Parcelable.Creator<PkImageData> CREATOR = new Parcelable.Creator<PkImageData>() { @Override public PkImageData createFromParcel(Parcel source) { PkImageData pkImageData = new PkImageData(); pkImageData.PKID = source.readInt(); pkImageData.Name = source.readString(); pkImageData.Logo = source.readString(); pkImageData.SenderID = source.readInt(); pkImageData.VisitNum = source.readInt(); pkImageData.TotalVisitNum = source.readInt(); return pkImageData; } @Override public PkImageData[] newArray(int size) { return null; } }; @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(PKID); dest.writeString(Name); dest.writeString(Logo); dest.writeInt(SenderID); dest.writeInt(VisitNum); dest.writeInt(TotalVisitNum); } }
注意: 从上面我们可以看出Parcel的写入和读出顺序是一致的。如果元素是list读出时需要先new一个ArrayList传入,否则会报空指针异常。如下:
list = new ArrayList<String>(); in.readStringList(list);