概述
序列化与反序列化是Android中进程间通信常用的手段之一,Serializable和Parcelable都可以实现对象的序列化和反序列化,Serializable是Java提供的,属于统一接口,而Parcelable是Android提供的,属于Android特有的。
Serializable
Serializable是一个空接口。
public interface Serializable {
}
使用也非常简单,实现该接口就行。
public class Person implements Serializable {
// 可以有,可以没有
private static final long serialVersionUID = 8004414918500865564L;
// private static final long serialVersionUID = 1L;
public int age;
public String name;
public Person(int age, String name) {
this.age = age;
this.name = name;
}
}
serialVersionUID
serialVersionUID相当于版本号,用于版本控制,不一致说明对象发生了变化,无法正常反序列化。指定1L或去掉生成的hash值即可。
使用
- 序列化
// 序列化
Person person = new Person(20, "java");
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("person.txt"));
out.writeObject(person);
out.close();
- 反序列化
// 反序列化
ObjectInputStream in = new ObjectInputStream(new FileInputStream("person.txt"));
Person p = (Person) in.readObject();
in.close();
序列化与反序列化前后的对象虽然内容一样,但不是同一个对象,相当于深拷贝。
注意
- 静态成员变量不能序列化,因为它属于类,不属于对象。
- transient标记的成员变量也不参与序列化。
Parcelable
Parcelable在Android中使用的比较多,常用的Intent就默认实现了Parcelable接口。
public class Intent implements Parcelable, Cloneable {
Bundle一样的。
public void putParcelable(@Nullable String key, @Nullable Parcelable value) {
描述
相比于Serializable,Parcelable使用要复杂一些。需要实现Parcelable 接口,并重写相关方法。
public class Person implements Parcelable {
public int age;
public String name;
public Person(int age, String name) {
this.age = age;
this.name = name;
}
- 从序列化后的对象中创建原始对象
/**
* 从序列化后的对象中创建原始对象
* @param in
*/
protected Person(Parcel in) {
age = in.readInt();
name = in.readString();
}
- 反序列化
/**
* 反序列化
*/
public static final Creator<Person> CREATOR = new Creator<Person>() {
/**
* 从序列化后的对象中创建新的原始对象
* @param in
* @return
*/
@Override
public Person createFromParcel(Parcel in) {
return new Person(in);
}
/**
* 创建指定长度的原始对象的数组
* @param size
* @return
*/
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
- 内容描述
/**
* 内容描述
* @return 1:CONTENTS_FILE_DESCRIPTOR,仅当对象中有文件描述符时返回
* 其他都应该返回0
*/
@Override
public int describeContents() {
return 0;
}
- 将当前对象写入序列化对象中
/**
* 将当前对象写入序列化对象中
* @param dest 序列化对象
* @param flags 0:绝大多数情况都是0
* 1:PARCELABLE_WRITE_RETURN_VALUE
* 表示当前对象需要作为返回值返回,不需要立即释放资源
*/
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(age);
dest.writeString(name);
}
使用
Bundle bundle = new Bundle();
bundle.putParcelable("test",new Person(18,"android"));
比较
Serializable | Parcelable | |
---|---|---|
平台 | Java | Android |
使用 | 简单 | 稍复杂 |
效率 | 一般,有大量的IO开销 | 开销小,挺快 |
场景 | 网络或存储 | 内部传递 |