序列化和反序列化

序列化 (Serialization),实际上就是把对象的状态信息转换为可以存储或传输的形式的过程。进行数据传递时,必须要完成对象的序列化
运行时的对象状态转换成二进制,然后保存到流或者内存或者通过网络传输给其他端。
例如,通过将对象序列化到剪贴板,可在不同的应用程序之间共享对象。

1.Serializable接口

1.1 用法

a.直接实现这个接口。
b.对象的序列化通过ObjectOutputStream.writeObject完成
c.反序列化则是通过ObjectInputStream.readObject完成
缺点是,两者不是同一个对象。

1.2 Serializable的缺点

整个对象都进行传递,开销很大,序列化和反序列化的过程需要大量的io操作。没必要

1.3 SerialVersionUID(序列化的标识)

1
2
3
4
5
6
7
UID的作用,就相当于一个tag,作为唯一标识,可以写成1L
如果不写这个serialVersionUID(哈希值),序列化的过程中没什么影响
但是对反序列化readObject时会报错。
eclipse会自动生成,而在as则不会。as的生成顺序
preferences->Inspections->
serialization issues->
Serializable class without 'serialVersionUID' 勾上确认就可以
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等,都是实现了序列化
intent

bundle

bitmap

同时list和map也可以序列化,前提是其子元素都是可序列化的。

3. 如何抉择

网络中传递对象或者进程中传递,如Activity之间传输数据
则用Parcelable更好,其底层是binder通信。

而作为永久存储对象的话,则还是建议用Serializable
因为parcelable只是方便IPC,如果改变任何Parcel中数据的底层实现都可能导致之前的数据不可读取,所以此时还是建议使用Serializable。

igding wechat
2018 依计行事 持续精进
坚持原创技术分享,您的支持将鼓励我继续创作!