前言
在 Android 应用开发中,经常需要在 Activity 间传递参数,有时还需要传递 Java 对象。而传递对象有两种实现方式,一种是使类实现 android.os.Parcelable 接口,另外一种是使类实现 Serializaable
接口。
当一个类实现了 Parcelable 或 Serializaable 接口后,这个类的对象,就能通过 Intent 在 Activity 之间传递了。本文主要讲述 Parcelable 的应用,及 Parcelable 与 Serializaable 的对比。
Parcelable 的应用
使用 Parcelable 接口,让一个类对象能够打包或解包,有两个重要的步骤要做,
对象打包
对象打包,实际上就是将当前对象打包为 Parcel 对象的过程。
在实现 Parcelable 接口的类里,重写 Parcelable.writeToParcel(Parcel dest, int flags) 方法,用来将当前对象的一些域值按顺序写入到 dest 对象。代码示例如下,
import android.os.Parcel;
import android.os.Parcelable;
public class ParcelableDemo implements Parcelable {
private int mIntProp1;
private String mStrProp2;
private long mLongProp3;
...
...
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mIntProp1);
dest.writeString(mStrProp2);
dest.writeLong(mLongProp3);
}
}
在上面的 writeToParcel 方法中,将三个属性值依次写入到了 dest 对象,完成了对象的打包,后续传递的也是这个 Parcel 对象。
对象解包
解包的过程,实际就是将 Parcel 对象转为实际对象的过程。
对象解包时,需要在类里面提供一个类型为 Create 的 public 域,名字固定为 CREATOR,主要作用就是根据传入的 Parcel 对象,创建一个类型为 T 的对象。
CREATOR 实现了 Parcelable.Creator 接口,并实现了他的两个方法 createFromParcel(Parcel source) 和 newArray(int size) 方法。代码示例如下,
import android.os.Parcel;
import android.os.Parcelable;
public class ParcelableDemo implements Parcelable {
private int mIntProp1;
private String mStrProp2;
private long mLongProp3;
public static final Creator<ParcelableDemo> CREATOR = new Creator<ParcelableDemo>() {
@Override
public ParcelableDemo createFromParcel(Parcel source) {
return new ParcelableDemo(source);
}
@Override
public ParcelableDemo[] newArray(int size) {
return new ParcelableDemo[size];
}
};
public ParcelableDemo(Parcel in) {
mIntProp1 = in.readInt();
mStrProp2 = in.readString();
mLongProp3 = in.readLong();
}
...
...
}
在上面的代码中,通过传入的 Parcel 对象,创建出来了 ParcelableDemo 对象,完成了解包的过程。通过上面两个步骤,ParcelableDemo 对象就可以通过 Intent 在 Activity 之间传递了。
Parcelable 与 Serializable 对比
以下整理出来几点这两个接口之间的对比,
- Parcelable 是 Android SDK 提供的一个接口,用来实现 Java 对象的打包和解包;Serializable 是 Java 提供的一个序列化和反序列化接口。
- 使用 Parcelable 时,开发者可以自定义打包和解包规则,并且 Android 中有要求,如果没有自定义规则,很可能会无法得到预期结果。而在使用 Serializable 接口时,不进行自定义序列化和反序列化规则,也能够正常使用,所以很多情况下,在 Android 中使用 Parcelable 时,会比使用 Serializable 产生更少的垃圾对象,性能也比 Serializable 更好。
- 当使用 Serializable 接口时,自定义序列化和反序列化规则,不会产生多余的垃圾,处理速度也会大幅提升,性能甚至会超过使用 Parcelable 接口。
下面是一张使用 Parcelable 和未自定义 Serializable 的对比图,从图中可以明显看到 Parcelable 的性能要更好,
至于使用自定义 Serializable 的对比图,有兴趣的可以试试。
总结
通过实现 Parcelable 接口,可以在 Activity 间传递自定义的 Java 对象,Android 提供了一整套机制来支持 Parcel。使用 Serializable 接口时,当没有自定义序列化规则时,性能要比使用 Parcelable 差很多。
参考链接:https://android.jlelse.eu/parcelable-vs-serializable-6a2556d51538