Serializable - Java原生的序列化方案
Parcelable - android提供的序列化方案
Serializable接口的使用
空接口,類只需要聲明 implements Serializable, 并提供一個serialVersionUID值即可.
使用ObjectOutputStreamd和ObjectInputStream就可以把一個對象寫入文件和從文件讀取出來.
寫入文件:
LoggingInfo logInfo = new LoggingInfo("MIKE", "MECHANICS");
FileOutputStream fos = new FileOutputStream("c:\\logging.obj");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(logInfo);
oos.close();
讀取文件:
FileInputStream fis = new FileInputStream("c:\\logging.obj");
ObjectInputStream ois = new ObjectInputStream(fis);
LoggingInfo info = (LoggingInfo) ois.readObject();
ois.close();
提供serialVersionUID值的目的
系統(tǒng)序列化和反序列化時, 使用這個值來判斷在這2次操作之間, 類的結(jié)構(gòu)是否發(fā)生了變化。
如果不提供這個值的話, 系統(tǒng)會根據(jù)當(dāng)前類的結(jié)構(gòu)自動生成serialVersionUID值,如果serialVersionUID的值發(fā)生了變化,
或者即便serialVersionUID兩次相同, 但由于類結(jié)構(gòu)發(fā)生的變化(例如:改變了類中某個成員變量的類型)導(dǎo)致無法完成反序列化操作, 系統(tǒng)會報異常終止操作.
靜態(tài)成員變量和transient標(biāo)記的變量不參與序列化
靜態(tài)成員變量屬于類不屬于對象, 因此不參與序列化過程.
有些敏感變量值, 比如用戶的密碼不希望被序列化, 就可以用transient標(biāo)記而不參與序列化.
Parcelable接口的使用
使用起來稍顯復(fù)雜, 需要自己實現(xiàn)3個方法:
writeToParcel(Parcel dest, int flags)
內(nèi)部接口Creator里的createFromParcel(Parcel source)
describeContents()
Demo:
public class MyParcelable implements Parcelable {
private int mData;
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel out, int flags) {
out.writeInt(mData); //通過Parcel的一系列write方法實現(xiàn)序列化
}
public static final Parcelable.Creator<MyParcelable> CREATOR
= new Parcelable.Creator<MyParcelable>() {
public MyParcelable createFromParcel(Parcel in) {
return new MyParcelable(in);//內(nèi)部實現(xiàn)上, 通過Parcel的一系列read方法實現(xiàn)反序列化
}
public MyParcelable[] newArray(int size) {
return new MyParcelable[size];
}
};
private MyParcelable(Parcel in) {
mData = in.readInt();
}
}
Parcelable接口最常見的用處.
如果某個類的對象需要設(shè)置給Intent中的Bundle對象, 那么這個類要實現(xiàn)Parcelable或Serializable接口.
通?;谛士紤], 這個類選擇實現(xiàn)Parcelable接口.
public class Intent implements Parcelable, Cloneable {
private Bundle mExtras;
public Intent putExtra(String name, Parcelable value) {
mExtras.putParcelable(name, value);
return this;
}
public Intent putExtra(String name, Serializable value) {
mExtras.putSerializable(name, value);
return this;
}
}
Bundle其實就是一個保存K,V數(shù)據(jù)的Map.
/**
* Bundle Class
* A mapping from String K to various Parcelable types V.
*
*/
public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
}
Serializable接口和Parcelable接口都能實現(xiàn)序列化,選擇哪個?
Parcelable主要用于把對象序列化后,以K,V的形式設(shè)置給intent中的bundle.這個intent對象攜帶著這個數(shù)據(jù),
傳遞給其他進程使用, 實現(xiàn)跨進程的數(shù)據(jù)傳遞.
Intent intent = new Intent();
intent.putExtra("downloadParam", mDownloadParam);
雖然通過Parcelable也可以實現(xiàn)把對象寫入存儲設(shè)備或是把對象序列化后通過網(wǎng)絡(luò)傳輸,
但實現(xiàn)起來比較復(fù)雜, 因此這兩種情況下一般還是使用Serializable接口.
Android里面為什么要設(shè)計出Bundle而不是直接讓Intent使用Map結(jié)構(gòu)承載數(shù)據(jù)
Map里實現(xiàn)了Serializable接口,而Bundle實現(xiàn)了Parcelable的接口.
基于執(zhí)行效率的考慮(比 JDK 自帶的 Serializable 效率高),讓Intent使用Bundle結(jié)構(gòu).
宏觀上說, Bundle實際上就是一個特殊的Map.
intent傳遞數(shù)據(jù)時,數(shù)據(jù)大小的限制在1Mb以內(nèi)
因此不要使用intent直接傳遞bitmap對象, 否則容易發(fā)生crash.
詳見:
http://blog.csdn.net/a568078283/article/details/46681321
----DONE.-----------