序列化 (Serialization),实际上就是把对象的状态信息转换为可以存储或传输的形式的过程。进行数据传递时,必须要完成对象的序列化
运行时的对象状态转换成二进制,然后保存到流或者内存或者通过网络传输给其他端。
例如,通过将对象序列化到剪贴板,可在不同的应用程序之间共享对象。
1.Serializable接口
1.1 用法
a.直接实现这个接口。
b.对象的序列化通过ObjectOutputStream.writeObject完成
c.反序列化则是通过ObjectInputStream.readObject完成
缺点是,两者不是同一个对象。
1.2 Serializable的缺点
整个对象都进行传递,开销很大,序列化和反序列化的过程需要大量的io操作。没必要
1.3 SerialVersionUID(序列化的标识)
1 | UID的作用,就相当于一个tag,作为唯一标识,可以写成1L |
1.3.1 详细的工作机制:
序列化的时候,系统将类的uid写入序列化文件。
反序列化时,系统会检测UID,看与当前类的是否一致,一致的话,则
说明序列化的类版本和当前类的版本相同。这个时候就可以成功反序列化。
2.Android特有的序列化方式。Parcelable
实现了Parcelable,就完成序列化,并通过intent和binder来传递。
public class Student implements Parcelable {
String name;
String age;
protected Student(Parcel in) {
name = in.readString();
age = in.readString();
}
//实现序列化
@Override
public void writeToParcel(Parcel dest, int flags) {
//dest内部包装了可序列化的数据,可以在binder中传递
dest.writeString(name);
dest.writeString(age);
}
@Override
public int describeContents() {
return 0;
}
//反序列化功能,创建序列化对象和数组。
public static final Creator<Student> CREATOR = new Creator<Student>() {
@Override
public Student createFromParcel(Parcel in) {
//in来实现反序列化。
return new Student(in);
}
@Override
public Student[] newArray(int size) {
return new Student[size];
}
};
}
例如 Android底层 如intent,bundle,bitmap等,都是实现了序列化
同时list和map也可以序列化,前提是其子元素都是可序列化的。
3. 如何抉择
网络中传递对象或者进程中传递,如Activity之间传输数据
则用Parcelable更好,其底层是binder通信。
而作为永久存储对象的话,则还是建议用Serializable
因为parcelable只是方便IPC,如果改变任何Parcel中数据的底层实现都可能导致之前的数据不可读取,所以此时还是建议使用Serializable。