对象的序列化
1. 概述
搞Android的小伙伴我估计大家都用过对象的序列化,因为在我们使用Intent或者Binder传输对象数据以及SharedPreferences存储对象数据时,都需要将我们的实体类对象序列化,实现的方式很简单,实现Serializable或者Parcelable两种方式,接下来就简介的介绍一下这两种方式以及优劣势。
2. Serializable接口
- Java提供的序列化接口
- 空接口,空实现,实现简单
- implements Serializable接口
- 提供一个long类型的声明如下代码(非必需的,可提供不可提供)
public class Person implements Serializable {
// 类型声明
private static final long serialVersionUID = 1L;
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
疑问:GreenDao数据库实现Serializable的接口必须得提供一个声明,为什么
不手动指定serialVersionUID的值.反序列化时,当实体类有所改变,
比如增加或者删除了某些成员变量,此时当前类的serialVersionUID和之前序列化的serialVersionUID不一致,就会导致程序挂掉。
但是如果类发生了毁灭性的非常规性改变时,反序列化过程还是会失败,无法从老版本数据还原。这就是GreenDao在实现Serializable接口时必须提供一个声明。
3. Parcelable接口
- Android提供的序列化接口
- 需要实现序列化(writeToParcel)、反序列化(CREATOR)和内容描述(describeContents)
public class Person implements Parcelable {
public String name;
public int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
protected Person(Parcel in) {
name = in.readString();
age = in.readInt();
}
public static final Creator<Person> CREATOR = new Creator<Person>() {
@Override
public Person createFromParcel(Parcel in) {
return new Person(in);
}
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
// 仅当前对象中存在文件描述符时,此方法返回
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeInt(age);
}
}
4. 两者的区别
- Serializable是Java中的序列化接口,使用简单,但是开销很大,序列化和反序列化都需要做大量的IO操作;
- Parcelable是Android中的序列化接口,主要用在内存序列化上,更加适合Android,缺点就是使用起来麻烦点,效率高,Android推荐使用方式;
网友评论