Android中的两种序列化:Parcelable和Serialable
Android开发中常常用到序列化,典型的应用就是Intent携带数据(不宜携带过多数据)。跨进程传输是将对象序列化,转换成可存储或可传输的状态,再通过网络等方式传输。
public class Intent implements Parcelable, Cloneable {
...
}
Intent之所以能够跨进程传输因为它实现了Android特有的序列化接口Serialable。这也是开发中用到序列化的原因之一:
①永久性保存对象,保存对象的字节序列到本地文件
②通过序列化对象在网络中传递对象
③通过序列化对象在进程间传递对象
1、Serialable*
Serialable是Java自带的序列化接口:表示将一个对象转换成可存储或可传输的状态。序列化后的对象可以在网络上进行传输,也可以存储到本地。
public interface Serializable {
}
需要序列化的类,实现Serialable接口声明一下该类需要序列化即可:
public class Info implements Serializable {
private static final long serialVersionUID = 974450303339087901L;
private String name;
}
注意需要提供一个serialVersionUID常量,标识独一无二的一个类。参考生成Serializable接口serialVersionUID。
2、Parcelable
Parcelable序列化是Android独有的序列化方式。
为什么不直接采用Java自带的Serialable序列化呢?Serializable效率过慢,而Parcelable比Serializable性能高。Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC。对于Android应用程序运行在移动设备上,对性能有一定的要求。
2.1、Parcelable接口
①两个抽象方法,序列化必须要实现:
public int describeContents():内容描述接口,不用管。返回0即可。
public void writeToParcel(Parcel dest, int flags):数据写入序列流接口。
②两个接口:必须创建实现Creator<T>接口的静态实例,并且名称为CREATOR。
Creator<T>,必须作为公共CREATOR字段实现并提供的接口,该字段从Parcel生成Parcelable类的实例T。
public interface Creator<T> {
/**
* 创建Parcelable类的新实例,然后从给定的Parcel实例化该实例。该数据先前由Parcelable#writeToParcel写入
*/
public T createFromParcel(Parcel source);
/**
* 创建一个新的Parcelable类数组
*/
public T[] newArray(int size);
}
ClassLoaderCreator<T>继承自Creator<T>,基本用不到
public interface ClassLoaderCreator<T> extends Creator<T> {
/**
* Create a new instance of the Parcelable class
*/
public T createFromParcel(Parcel source, ClassLoader loader);
}
2.2、标准示例
通过Parcelable序列化的典型实现代码如下:
public class MyParcelable implements Parcelable {
private int mData;
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel out, int flags) {
out.writeInt(mData);
}
public static final Parcelable.Creator<MyParcelable> CREATOR
= new Parcelable.Creator<MyParcelable>() {
public MyParcelable createFromParcel(Parcel in) {
return new MyParcelable(in);
}
public MyParcelable[] newArray(int size) {
return new MyParcelable[size];
}
};
private MyParcelable(Parcel in) {
mData = in.readInt();
}
}
三个要点:实现两个接口方法;创建一个实现Creator<T>接口的静态实例,并且名称为CREATOR;数据序列化顺序和反序列化顺序要一致。
如果需要序列化的类属性过多,一个一个写起来挺麻烦。推荐一个Parcelable序列化插件款速实现Parcelable序列化。
2.3、序列化流程
略。这块源码可以从Intent携带数据时的putExtra(String name, Parcelable value)方法,再到获取时的getParcelableExtra(String name)方法看起。了解完整的序列化和反序列化流程。
与序列化相关的Native层源码在../frameworks/native/libs/binder/Parcel.cpp中。
3、总结
①Serializable是Java自带的序列化方式,Parcelable是Android特有的序列化方式。
②Serializable序列化会产生大量的临时变量,引起频繁的GC,造成内存抖动,不适合Android应用程序。
③Parcelable比Serializable性能高、效率高,Android开发中使用Parcelable。
④Serializable可以将对象通过网络传输 或 磁盘存储。Parcelable无法将对象保存在存储中。
参考资料:
Android Developers > Reference > Parcelable
Android Developers > Reference > Parcelable.Creator
Android之Parcelable解析
程序员必懂小技巧之Parcelable