Parcelable
這是一個接口,它的實例可以寫入Parcel
或從Parcel
恢復(fù)。實現(xiàn)Parcelable
的類必須要有一個實現(xiàn)了Parcelable.Creator
接口的類型的非空靜態(tài)字段CREATOR
,這個字段是幫忙從一個Parcel
產(chǎn)生一個Parcelable
類的實例桌吃。
public class MyParcelable implements Parcelable {
private int mData;
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel out, int flags) {
out.writeInt(mData);
}
public static final Parcelable.Creator<MyParcelable> CREATOR
= new Parcelable.Creator<MyParcelable>() {
public MyParcelable createFromParcel(Parcel in) {
return new MyParcelable(in);
}
public MyParcelable[] newArray(int size) {
return new MyParcelable[size];
}
};
private MyParcelable(Parcel in) {
mData = in.readInt();
}
}
- describeContents()用于描述
Parcelable
類實例的 - writeToParcel(Parcel dest, int flags)用于將數(shù)據(jù)扁平化寫入
Parcel
Parcel
是一個消息(數(shù)據(jù)或?qū)ο笠茫┤萜靼危梢酝ㄟ^IBinder
來發(fā)送,也就是說 Parcelable
實例十分合適作來進(jìn)程間通信的消息載體搬卒。
在java
中使用Serializable
接口實現(xiàn)對象的序列化,而在android中既可以使用Serializable
也可以使用Parcelable
接口實現(xiàn)對象序列化契邀,如果只在內(nèi)存操作時則傾向Parcelable
接口,傳輸效率會更高效坯门。
注意:Parcelable
只能對內(nèi)存對象序列化,不能對需要存儲在文件或SD等設(shè)備進(jìn)行序列化古戴,如果需要將對象序列化存儲到文件,實現(xiàn)Serializable
接口就可以了
Serializable
是java
提供的一個序列化接口现恼,它是一個空接口黍檩,專門為對象提供標(biāo)準(zhǔn)的序列化和反序列化操作,用它實現(xiàn)類的序列化比較簡單建炫,只要在類聲明中實現(xiàn)Serializable
接口即可。
public class User implements Serializable {
private static final long serialVersionUID = -4454266436543306544L;
private String name;
/**
* age
*/
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
由于serialVersionUID
是用來輔助序列化和反序列化過程的,原則上序列化后的對象中serialVersionUID
只有和當(dāng)前類的serialVersionUID
相同才能夠正常被反序列化艺配,也就是說序列化與反序列化的serialVersionUID
必須相同才能夠使序列化操作成功。序列化操作的時候系統(tǒng)會把當(dāng)前類的serialVersionUID
寫入到序列化文件中转唉,當(dāng)反序列化時系統(tǒng)會去檢測文件中的serialVersionUID
,判斷它是否與當(dāng)前類的serialVersionUID
一致赠法,如果一致就說明序列化類的版本與當(dāng)前類版本是一樣的麦轰,可以反序列化成功砖织,否則失敗。因此強烈建議指定serialVersionUID
侧纯,這樣的話即使微小的變化也不會導(dǎo)致crash的出現(xiàn),否則文件多一個空格或類的結(jié)構(gòu)有些許變化都會反序列化失敗眶熬。默認(rèn)情況下妹笆,系統(tǒng)會根據(jù)類結(jié)構(gòu)自動生成的serialVersionUID
,因此當(dāng)類稍有變化娜氏,自動生成的UID就會與之前存在文件中的不一樣,就會反序列化失敗贸弥。因此有必要指定serialVersionUID
,那么系統(tǒng)就會盡可能地序列化茂腥。
需要注意的是如果反序列的類的成員變量的類型或者類名發(fā)生了變化,即使serialVersionUID
相同反序列化會失敗最岗。其次是靜態(tài)成員變量屬于類不屬于對象,不會參與序列化過程般渡,使用transient關(guān)鍵字標(biāo)記的成員變量也不參與序列化過程芙盘。
Serializable
在內(nèi)存序列化是(將數(shù)據(jù)持久化在磁盤)上開銷比較大,如Serializable
在序列化的時候會產(chǎn)生大量的臨時變量脸秽,從而引起頻繁的GC(垃圾回收),而內(nèi)存資源對于android系統(tǒng)來說是十分稀有的(首先记餐,我們每個應(yīng)用都會運行在各自的虛擬機上,而android系統(tǒng)分配給每個虛擬機的內(nèi)存開銷都是十分有限的)片酝。因此android中提供了Parcelable
接口來實現(xiàn)序列化操作,Parcelable
的性能比Serializable
好雕沿,在內(nèi)存開銷方面較小,所以在內(nèi)存間數(shù)據(jù)傳輸時推薦使用Parcelable
审轮,如通過Intent
在activity間傳輸數(shù)據(jù),進(jìn)程間通信也推薦使用Parcelable