[关闭]
@linux1s1s 2019-02-14T01:53:51.000000Z 字数 2803 阅读 3318

Android 序列化比对

AndroidExtend 2015-04


在Android中使用序列化,无非两种途经: ParcelableSerializable

两者区别

Serializable

  1. public class SerializableDeveloper implements Serializable
  2. String name;
  3. int yearsOfExperience;
  4. List<Skill> skillSet;
  5. float favoriteFloat;
  6. static class Skill implements Serializable {
  7. String name;
  8. boolean programmingRelated;
  9. }
  10. }

serializable的迷人之处在于你只需要对某个类以及它的属性实现Serializable 接口即可。Serializable 接口是一种标识接口(marker interface),这意味着无需实现方法,Java便会对这个对象进行高效的序列化操作。
这种方法的缺点是使用了反射,序列化的过程较慢。这种机制会在序列化的时候创建许多的临时对象,容易触发垃圾回收。

Parcelable

  1. class ParcelableDeveloper implements Parcelable {
  2. String name;
  3. int yearsOfExperience;
  4. List<Skill> skillSet;
  5. float favoriteFloat;
  6. ParcelableDeveloper(Parcel in) {
  7. this.name = in.readString();
  8. this.yearsOfExperience = in.readInt();
  9. this.skillSet = new ArrayList<Skill>();
  10. in.readTypedList(skillSet, Skill.CREATOR);
  11. this.favoriteFloat = in.readFloat();
  12. }
  13. void writeToParcel(Parcel dest, int flags) {
  14. dest.writeString(name);
  15. dest.writeInt(yearsOfExperience);
  16. dest.writeTypedList(skillSet);
  17. dest.writeFloat(favoriteFloat);
  18. }
  19. int describeContents() {
  20. return 0;
  21. }
  22. static final Parcelable.Creator<ParcelableDeveloper> CREATOR
  23. = new Parcelable.Creator<ParcelableDeveloper>() {
  24. ParcelableDeveloper createFromParcel(Parcel in) {
  25. return new ParcelableDeveloper(in);
  26. }
  27. ParcelableDeveloper[] newArray(int size) {
  28. return new ParcelableDeveloper[size];
  29. }
  30. };
  31. static class Skill implements Parcelable {
  32. String name;
  33. boolean programmingRelated;
  34. Skill(Parcel in) {
  35. this.name = in.readString();
  36. this.programmingRelated = (in.readInt() == 1);
  37. }
  38. @Override
  39. void writeToParcel(Parcel dest, int flags) {
  40. dest.writeString(name);
  41. dest.writeInt(programmingRelated ? 1 : 0);
  42. }
  43. static final Parcelable.Creator<Skill> CREATOR
  44. = new Parcelable.Creator<Skill>() {
  45. Skill createFromParcel(Parcel in) {
  46. return new Skill(in);
  47. }
  48. Skill[] newArray(int size) {
  49. return new Skill[size];
  50. }
  51. };
  52. @Override
  53. int describeContents() {
  54. return 0;
  55. }
  56. }
  57. }

根据 google 工程师的说法,这些代码将会运行地特别快。原因之一就是我们已经清楚地知道了序列化的过程,而不需要使用反射来推断。同时为了更快地进行序列化,对象的代码也需要高度优化。
因此,很明显实现Parcelable并不容易。实现Parcelable接口需要写大量的模板代码,这使得对象代码变得难以阅读和维护。

性能测试

通过将一个对象放到一个bundle里面然后调用Bundle#writeToParcel(Parcel, int)方法来模拟传递对象给一个activity的过程,然后再把这个对象取出来,在一个循环里面运行1000 次。

此处输入图片的描述

小结

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

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

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

另外有一种说法是:在Activity之间传递数据使用Serializable在某种情况下会失败,这样的案例尚未遇到过。(个人猜测:难道是持久化数据需要写入扩展SD卡,如果一旦出现写入或者读取失败,那么传输就会失败)

本文翻译和整理自:http://www.developerphil.com/parcelable-vs-serializable/

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注