Android序列化
Android序列化主要有Serializable和Parcelable两种,实现这两个接口可以完成对象的序列化过程。
什么时候应该使用序列化
当需要通过Intent和Binder传输数据时就需要使用Serializable或者Parcelable。
当需要将把对象通过网络传输给其他客户端或持久化在存储设备中则需要使用Serializable。
关于Serializable
只需要给实体类实现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方法即可达到对象序列化后网络传输或持久化到存储设备中。
serivalVersionUID是用于验证序列化与反序列化时否为相同的实体类,为了避免反序列化过程的失败,需要保持serivalVersionUID一致。
注:
实体类中的静态成员变量、用tranisent关键字标记的成员变量不参与序列化过程。
关于Parcelable
只需要给实体类实现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
//从序列化后的对象中创建原始对象
public App createFromParcel(Parcel source) {
return new App(source);
}
@Override
//创建指定长度的原始对象数组
public App[] newArray(int size) {
return new App[size];
}
};
public App(String id, String version) {
this.id = id;
this.version = version;
}
//从序列化后的对象中创建原始对象
public App(Parcel source) {
id = source.readString();
version = source.readString();
}
@Override
//当前对象内容描述符,有文件描述符返回1
//大多数情况都是返回0
public int describeContents() {
return 0;
}
@Override
//将当前对象写入序列化结构中,flag有0与1两种值
//当flag为1时,标识当前对象需要作为返回值返回,不能立即释放资源
//大多数情况都为0
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(id);
dest.writeString(version);
}
}
如果需要序列化的实体类A存在自定义的实体类B,那么在序列化实体类A的时候,需要保证实体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;
}
}
系统提供许多可以直接序列化的类,比如Intent、Bundle、Bitmap等,同时List和Map也可以序列化,前提它们里面的每个元素都是可以序列化的。
Serializable和Parcelable的区别
Serializable是Java中的序列化接口,用起来简单但是开销很大,序列化和反序列化过程需要大量的I/O操作,容易造成OOM。
Parcelable是Android的序列化接口,使用起来比较麻烦(But如果你使用的是AS,可以使用Parcelable插件),但是效率很高。
一般在Intent之间的数据传递和建议使用Parcelable,而网络数据传输或者数据持久化则使用Serializable。