Android序列化
Android序列化主要有Serializable和Parcelable兩種,實(shí)現(xiàn)這兩個(gè)接口可以完成對象的序列化過程政供。
什么時(shí)候應(yīng)該使用序列化
當(dāng)需要通過Intent和Binder傳輸數(shù)據(jù)時(shí)就需要使用Serializable或者Parcelable播聪。
當(dāng)需要將把對象通過網(wǎng)絡(luò)傳輸給其他客戶端或持久化在存儲(chǔ)設(shè)備中則需要使用Serializable。
關(guān)于Serializable
只需要給實(shí)體類實(shí)現(xiàn)Serializable接口
public class App implements Serializable{
private static final long serialVersionUID = 7530376661266598179L;
private String id;
private String version;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
}
只需要使用ObjectOutputStream的writeObject方法和ObjectInputStream的readObject方法即可達(dá)到對象序列化后網(wǎng)絡(luò)傳輸或持久化到存儲(chǔ)設(shè)備中布隔。
serivalVersionUID是用于驗(yàn)證序列化與反序列化時(shí)否為相同的實(shí)體類犬耻,為了避免反序列化過程的失敗,需要保持serivalVersionUID一致执泰。
注:
實(shí)體類中的靜態(tài)成員變量枕磁、用tranisent關(guān)鍵字標(biāo)記的成員變量不參與序列化過程。
關(guān)于Parcelable
只需要給實(shí)體類實(shí)現(xiàn)Parcelable接口
public class App implements Parcelable {
private String id;
private String version;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public static final Creator<App> CREATOR = new Creator<App>() {
@Override
//從序列化后的對象中創(chuàng)建原始對象
public App createFromParcel(Parcel source) {
return new App(source);
}
@Override
//創(chuàng)建指定長度的原始對象數(shù)組
public App[] newArray(int size) {
return new App[size];
}
};
public App(String id, String version) {
this.id = id;
this.version = version;
}
//從序列化后的對象中創(chuàng)建原始對象
public App(Parcel source) {
id = source.readString();
version = source.readString();
}
@Override
//當(dāng)前對象內(nèi)容描述符术吝,有文件描述符返回1
//大多數(shù)情況都是返回0
public int describeContents() {
return 0;
}
@Override
//將當(dāng)前對象寫入序列化結(jié)構(gòu)中计济,flag有0與1兩種值
//當(dāng)flag為1時(shí),標(biāo)識當(dāng)前對象需要作為返回值返回排苍,不能立即釋放資源
//大多數(shù)情況都為0
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(id);
dest.writeString(version);
}
}
如果需要序列化的實(shí)體類A存在自定義的實(shí)體類B沦寂,那么在序列化實(shí)體類A的時(shí)候,需要保證實(shí)體B也完成了序列化淘衙。
public class AppDetail implements Parcelable {
private App app;
private String name;
private String desc;
private long downloadTimes;
public static final Creator<AppDetail> CREATOR = new Creator<AppDetail>() {
@Override
public AppDetail createFromParcel(Parcel source) {
return new AppDetail(source);
}
@Override
public AppDetail[] newArray(int size) {
return new AppDetail[size];
}
};
public AppDetail(Parcel source) {
app = source.readParcelable(App.class.getClassLoader());
name = source.readString();
desc = source.readString();
downloadTimes = source.readLong();
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeParcelable(app, flags);
dest.writeString(name);
dest.writeString(desc);
dest.writeLong(downloadTimes);
}
public AppDetail(){
}
public App getApp() {
return app;
}
public void setApp(App app) {
this.app = app;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public long getDownloadTimes() {
return downloadTimes;
}
public void setDownloadTimes(long downloadTimes) {
this.downloadTimes = downloadTimes;
}
}
系統(tǒng)提供許多可以直接序列化的類传藏,比如Intent、Bundle彤守、Bitmap等毯侦,同時(shí)List和Map也可以序列化,前提它們里面的每個(gè)元素都是可以序列化的具垫。
Serializable和Parcelable的區(qū)別
Serializable是Java中的序列化接口侈离,用起來簡單但是開銷很大,序列化和反序列化過程需要大量的I/O操作筝蚕,容易造成OOM卦碾。
Parcelable是Android的序列化接口,使用起來比較麻煩(But如果你使用的是AS起宽,可以使用Parcelable插件)洲胖,但是效率很高。
一般在Intent之間的數(shù)據(jù)傳遞和建議使用Parcelable坯沪,而網(wǎng)絡(luò)數(shù)據(jù)傳輸或者數(shù)據(jù)持久化則使用Serializable绿映。