进行Android开发的时候,我们都知道不能将对象的引用传给Activities或者Fragments,我们需要将这些对象放到一个Intent或者Bundle里面,然后再传递。
通过Android的API,我们知道有两种选择,即在传递对象时,需要对我们的对象进行 Parcelable 或者Serializable化。作为Java开发者,相信大家对Serializable 机制有一定了解,那为什么还需要 Parcelable呢?
为了回答这个问题,让我们分别来看看这两者的差异。
Serializable, 简单易用
- // access modifiers, accessors and constructors omitted for brevity
- public class SerializableDeveloper implements Serializable
- String name;
- int yearsOfExperience;
- List<Skill> skillSet;
- float favoriteFloat;
- static class Skill implements Serializable {
- String name;
- boolean programmingRelated;
- }
- }
serializable的迷人之处在于你只需要对某个类以及它的属性实现Serializable 接口即可。Serializable 接口是一种标识接口(marker interface),这意味着无需实现方法,Java便会对这个对象进行高效的序列化操作。
这种方法的缺点是使用了反射,序列化的过程较慢。这种机制会在序列化的时候创建许多的临时对象,容易触发垃圾回收。
Parcelable, 速度至上
- // access modifiers, accessors and regular constructors ommited for brevity
- class ParcelableDeveloper implements Parcelable {
- String name;
- int yearsOfExperience;
- List<Skill> skillSet;
- float favoriteFloat;
- ParcelableDeveloper(Parcel in) {
- this.name = in.readString();
- this.yearsOfExperience = in.readInt();
- this.skillSet = new ArrayList<Skill>();
- in.readTypedList(skillSet, Skill.CREATOR);
- this.favoriteFloat = in.readFloat();
- }
- void writeToParcel(Parcel dest, int flags) {
- dest.writeString(name);
- dest.writeInt(yearsOfExperience);
- dest.writeTypedList(skillSet);
- dest.writeFloat(favoriteFloat);
- }
- int describeContents() {
- return 0;
- }
- static final Parcelable.Creator<ParcelableDeveloper> CREATOR
- = new Parcelable.Creator<ParcelableDeveloper>() {
- ParcelableDeveloper createFromParcel(Parcel in) {
- return new ParcelableDeveloper(in);
- }
- ParcelableDeveloper[] newArray(int size) {
- return new ParcelableDeveloper[size];
- }
- };
- static class Skill implements Parcelable {
- String name;
- boolean programmingRelated;
- Skill(Parcel in) {
- this.name = in.readString();
- this.programmingRelated = (in.readInt() == 1);
- }
- @Override
- void writeToParcel(Parcel dest, int flags) {
- dest.writeString(name);
- dest.writeInt(programmingRelated ? 1 : 0);
- }
- static final Parcelable.Creator<Skill> CREATOR
- = new Parcelable.Creator<Skill>() {
- Skill createFromParcel(Parcel in) {
- return new Skill(in);
- }
- Skill[] newArray(int size) {
- return new Skill[size];
- }
- };
- @Override
- int describeContents() {
- return 0;
- }
- }
- }
根据 google 工程师的说法,这些代码将会运行地特别快。原因之一就是我们已经清楚地知道了序列化的过程,而不需要使用反射来推断。同时为了更快地进行序列化,对象的代码也需要高度优化。
因此,很明显实现Parcelable并不容易。实现Parcelable接口需要写大量的模板代码,这使得对象代码变得难以阅读和维护。