Android系统中Parcelable和Serializable的区别

     进行Android开发的时候,咱们都知道不能将对象的引用传给Activities或者Fragments,咱们须要将这些对象放到一个Intent或者Bundle里面,而后再传递。android

 

经过Android的API,咱们知道有两种选择,即在传递对象时,须要对咱们的对象进行 Parcelable 或者Serializable化。做为Java开发者,相信你们对Serializable 机制有必定了解,那为何还须要 Parcelable呢?ide

 

为了回答这个问题,让咱们分别来看看这二者的差别。post

 

Serializable, 简单易用性能

 

public class SerializableDeveloper implements Serializable测试

   String name;优化

   int yearsOfExperience;this

   List<Skill> skillSet;google

   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接口须要写大量的模板代码,这使得对象代码变得难以阅读和维护。

 

速度测试

 

固然,咱们仍是想知道到底Parcelable相对于Serializable要快多少。

 

测试方法

 

经过将一个对象放到一个bundle里面而后调用Bundle#writeToParcel(Parcel, int)方法来模拟传递对象给一个activity的过程,而后再把这个对象取出来。

在一个循环里面运行1000 次。

两种方法分别运行10次来减小内存整理,cpu被其余应用占用等状况的干扰。

参与测试的对象就是上面代码中的SerializableDeveloper 和 ParcelableDeveloper。

在多种Android软硬件环境上进行测试

LG Nexus 4 – Android 4.2.2

Samsung Nexus 10 – Android 4.2.2

HTC Desire Z – Android 2.3.3

NEXUS 10

Serializable: 1.0004ms,  Parcelable: 0.0850ms – 提高10.16倍。

NEXUS 4

Serializable: 1.8539ms – Parcelable: 0.1824ms – 提高11.80倍。

DESIRE Z

Serializable: 5.1224ms – Parcelable: 0.2938ms – 提高17.36倍。

由此能够得出: Parcelable 比 Serializable快了10多倍。有趣的是,即便在Nexus 10这样性能强悍的硬件上,一个至关简单的对象的序列化和反序列化的过程要花将近一毫秒。

总结

若是你想成为一个优秀的软件工程师,你须要多花点时间来实现 Parcelable ,由于这将会为你对象的序列化过程快10多倍,并且占用较少的资源。

 

可是大多数状况下, Serializable 的龟速不会太引人注目。你想偷点懒就用它吧,不过要记得serialization是一个比较耗资源的操做,尽可能少使用。

 

若是你想要传递一个包含许多对象的列表,那么整个序列化的过程的时间开销可能会超过一秒,这会让屏幕转向的时候变得很卡顿。

 

英文原文:developerphil

译文来源:Android Cool Posts

连接:http://greenrobot.me/devpost/android-parcelable-serializ

相关文章
相关标签/搜索