一.基础
序列化(Serialization):将对象转换成二进制,然后保存到流、内存或者通过网络传输。
反序列化就是序列化的镜像,二进制转回对象。
Android的序列化有两种方式:Serializable和Parcelable
二.Serializable
Java提供的序列化接口,略。
优点:使用简单(Serializable只需要实现接口 提供一个serialVersionUID,Parcelable需要实现四个方法)
缺点:开销大【序列化过程中使用反射机制(JVM没法对反射相关代码做优化),大量IO操作产生大量临时变量导致频繁GC】、效率低
应用于:序列化到本地 或 通过网络传输。
三.Parcelable
Android特有的序列化接口。
设计初衷:Serializable太慢,为了在程序内不同组件间 和 不同进程间 高效传输对象而设计
开销小效率高,应用于运行时内存中数据传递,如通过Intent、Binder跨进程传递对象。
1.Parcel
包含对象的一个载体,通过IBinder在进程间传递。
2.Parcelable需要实现的方法
- (void)wiriteToParcel(Parcel out):将 待序列化对象中数据 写入 Parcel对象out
- (int)describeContents():默认返回0,除非要描述文件时返回1
- 静态CREATOR变量:
createFromParcel(Parcel in):反序列化,创建Parcel对象
newArray(int size):反序列创建对象数组
4.【可选】(void)readFromParcel(Parcel in):从 反序列化得到的Parcel对象 中 读取
3.demo
public final class Rect implements Parcelable {
public int left;
public static final Parcelable.Creator<Rect> CREATOR = new Parcelable.Creator<Rect>() {
@Override // 反序列创建对象
public Rect createFromParcel(Parcel in) {
return new Rect(in);
}
@Override // 反序列创建对象数组
public Rect[] newArray(int size) {
return new Rect[size];
}
};
public Rect() {//无参构造函数
}
private Rect(Parcel in) { //使用反序列化得到的 Parcel 来构造对象
readFromParcel(in);
}
@Override //写入序列化结构
public void writeToParcel(Parcel out) {
out.writeInt(left);
}
@Override //使用反序列化得到的 Parcel 来构造对象(抽出来而已)
public void readFromParcel(Parcel in) {
left = in.readInt();
}
@Override //几乎都返回 0,除非当前对象中存在文件描述符时为 1
public int describeContents() {
return 0;
}
}
其实就是打包、解包自己定义,具体的序列化、反序列化操作由系统实现。
实际编程中,有一键生成Parcelable代码的插件:Android Parcelable code generator。只需要写一个实体类,想序列化时使用插件就可以将实体类转换成实现Parcelable接口的形式。
四.参考文章
Android校招面试指南-Parcelable和Serializable的区别
Android 进阶:两种序列化方式 Serializable 和 Parcelable
Android数据序列化方案研究