話題:關(guān)于序列化的知識(shí)
1、Parcelable和Serializable有什么用,它們有什么差別?
(1) Parcelable的使用:
* public class MyParcelable implements Parcelable {
* private int mData;
*
* /*
* * Bit masks for use with {@link #describeContents}: each bit represents a
* * kind of object considered to have potential special significance when
* * marshalled.
* */
* public int describeContents() {
* //一共返回2種返回值 0 與 CONTENTS_FILE_DESCRIPTOR
* //一般返回0,特殊情況下返回CONTENTS_FILE_DESCRIPTOR
* 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();
* }
* }
通過writeToParcel將你的對(duì)象映射成Parcel對(duì)象,再通過createFromParcel將Parcel對(duì)象映射成你的對(duì)象。也可以將Parcel看成是一個(gè)流,通過writeToParcel把對(duì)象寫到流里面,在通過createFromParcel從流里讀取對(duì)象,只不過這個(gè)過程需要你來實(shí)現(xiàn),因此寫的順序和讀的順序必須一致。
(2) Serializable的使用:
Serializable的實(shí)現(xiàn),只需要implements Serializable 即可。這只是給對(duì)象打了一個(gè)標(biāo)記,系統(tǒng)會(huì)自動(dòng)將其序列化。
在序列化過程中會(huì)自動(dòng)生成一個(gè)serialVersionUID來標(biāo)識(shí)序列化對(duì)象。serialVersionUID是用來輔助序列化和反序列化過程的,序列化與反序列化的serialVersionUID必須相同才能夠使序列化操作成功。
具體過程是這樣的:序列化操作的時(shí)候系統(tǒng)會(huì)把當(dāng)前類的serialVersionUID寫入到序列化文件中,當(dāng)反序列化時(shí)系統(tǒng)會(huì)去檢測(cè)文件中的serialVersionUID,判斷它是否與當(dāng)前類的serialVersionUID一致,如果一致就說明序列化類的版本與當(dāng)前類版本是一樣的,可以反序列化成功,否則失敗。
報(bào)出如下UID錯(cuò)誤:
Exception in thread "main" java.io.InvalidClassException: com.android.test.Client;
local class incompatible: stream classdesc serialVersionUID =
-2656541345465468483
local class serialVersionUID = -1546464648434364595
(3)區(qū)別:
- Serializable接口(是JavaSE本身就支持的),Parcelable接口(是Android特有功能,效率比實(shí)現(xiàn)Serializable接口高效,可用于Intent數(shù)據(jù)傳遞,也可以用于進(jìn)程間通信(IPC))。
- 在使用內(nèi)存的時(shí)候,Parcelable比Serializable性能高,所以推薦使用Parcelable
(4)選取原則:
- 在使用內(nèi)存的時(shí)候,Parcelable比Serializable性能高,所以推薦使用Parcelable。
- Serializable在序列化的時(shí)候會(huì)產(chǎn)生大量的臨時(shí)變量,從而引起頻繁的GC。
- Parcelable不能使用在要將數(shù)據(jù)存儲(chǔ)在磁盤上的情況,因?yàn)镻arcelable不能很好的保證數(shù)據(jù)的持續(xù)性在外界有變化的情況下。盡管Serializable效率低點(diǎn), 也不提倡用,但在這種情況下,還是建議你用Serializable 。
2、自定義一個(gè)類讓其實(shí)現(xiàn)Parcelable,大致流程是什么?
見答案1。
3、枚舉如何實(shí)現(xiàn)Parcelable 接口
public enum Option implements Parcelable {
DATA_BASE("Database"), TRIPS("Trips");
private String option;
Option(String option){
this.option = option;
}
public String getName(){
return option;
}
private void setOption(String option){
this.option = option;
}
public static final Parcelable.Creator<Option> CREATOR = new Parcelable.Creator<Option>() {
public Option createFromParcel(Parcel in) {
Option option = Option.values()[in.readInt()];
option.setOption(in.readString());
return option;
}
public Option[] newArray(int size) {
return new Option[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeInt(ordinal());
out.writeString(option);
}
}