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

通过Android的API,我们知道有两种选择,即在传递对象时,需要对我们的对象进行 Parcelable 或者Serializable化。作为Java开发者,相信大家对Serializable 机制有一定了解,那为什么还需要 Parcelable呢?

为了回答这个问题,让我们分别来看看这两者的差异。

Serializable, 简单易用

  1. // access modifiers, accessors and constructors omitted for brevity
  2. public class SerializableDeveloper implements Serializable
  3. String name;
  4. int yearsOfExperience;
  5. List<Skill> skillSet;
  6. float favoriteFloat;
  7. static class Skill implements Serializable {
  8. String name;
  9. boolean programmingRelated;
  10. }
  11. }

serializable的迷人之处在于你只需要对某个类以及它的属性实现Serializable 接口即可。Serializable 接口是一种标识接口(marker interface),这意味着无需实现方法,Java便会对这个对象进行高效的序列化操作。

这种方法的缺点是使用了反射,序列化的过程较慢。这种机制会在序列化的时候创建许多的临时对象,容易触发垃圾回收。

Parcelable, 速度至上

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

根据 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

结果

parcelable-vs-serializable

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是一个比较耗资源的操作,尽量少使用。

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

Android系统中Parcelable和Serializable的区别相关推荐

  1. fileoutputstream路径 android,Android编程中FileOutputStream与openFileOutput()的区别分析

    本文实例分析了Android编程中FileOutputStream与openFileOutput()的区别.分享给大家供大家参考,具体如下: openFileOutput() 首先给大家介绍使用文件如 ...

  2. Android系统中的Binder通信机制分析(7)- Java 层的 Binder 机制

    声明 其实对于Android系统Binder通信的机制早就有分析的想法,记得2019年6.7月份Mr.Deng离职期间约定一起对其进行研究的,但因为我个人问题没能实施这个计划,留下些许遗憾- 文中参考 ...

  3. ZIP文件格式及其在android系统中的应用

    zip是一种归档文件格式,zip可以把若干文件和目录下的文件进行归档,这些归档的文件可以压缩也可以不压缩,并且压缩算法也是可以选择的,目前zip最经常使用的是deflate算法,因为zip中包含若干归 ...

  4. android流量控制的实现,Android系统中P2P应用数据包捕获及流量控制研究

    摘要: P2P应用产生的流量正大肆吞噬着网络带宽,增加了网络运营商的管理压力.同时随着以Android为主的移动设备用户群变得越来越庞大,相应的流量吸费问题也随之产生,特别是Android手机上的P2 ...

  5. 【Android 逆向】修改运行中的 Android 进程的内存数据 ( Android 系统中调试器进程内存流程 | 编译内存调试动态库以及调试程序 )

    文章目录 一.Android 系统中调试器进程内存流程 二.编译内存调试动态库以及调试程序 三.博客资源 一.Android 系统中调试器进程内存流程 修改游戏运行中的内存 , 游戏运行之后 , 游戏 ...

  6. 【Android 逆向】Android 权限 ( Android 逆向中使用的 android.permission 权限 | Android 系统中的 Linux 用户权限 )

    文章目录 一.Android 逆向中使用的 android.permission 权限 二.Android 系统中的 Linux 用户权限 一.Android 逆向中使用的 android.permi ...

  7. android界面布局题,【填空题】Android 系统中, 用于定义布局显示在界面上的风格。...

    [填空题]Android 系统中, 用于定义布局显示在界面上的风格. 更多相关问题 [37]A.anotherB.each otherC.the otherD.one another Tabor ma ...

  8. Android系统中的进程管理:内存的回收

    本文是Android系统进程管理的第三篇文章.进程管理的前面两篇文章,请参见这里: Android系统中的进程管理:进程的创建 Android系统中的进程管理:进程的优先级 本文适合Android平台 ...

  9. Android系统中的进程管理:进程的创建

    对于操作系统来说,进程管理是其最重要的职责之一. 考虑到这部分的内容较多,因此会拆分成几篇文章来讲解. 本文是进程管理系统文章的第一篇,会讲解Android系统中的进程创建. 本文适合Android平 ...

最新文章

  1. 清华 CVer 对自监督学习的一些思考
  2. 关于版本号:alpha、beta、rc、stable
  3. [leetcode] 874. 行走机器人模拟(周赛)
  4. Lua和C++交互详细总结
  5. 关于 Orbeon form PE 版本使用 JavaScript Embedding API 的一个例子
  6. 计算机学院迎新晚会集宁,迎新晚会 | 信息管理学院2017年“海姆达尔之眼”迎新晚会圆满成功...
  7. 1、python基础速成
  8. matlab样条插值如何用,三次样条插值matlab实现
  9. 常用技巧 —— 位运算 —— 异或运算实现两个数的交换
  10. 下载eclipse出现a java_java - 运行eclipse出现问题?
  11. python 验证码识别 阿里云_python3调用阿里云图像识别OCR-实现验证码识别
  12. ClassLoader背景知识
  13. 自制公众平台Web Api(微信)
  14. PTA 程序设计天梯赛(141~160题)
  15. 网络流之P3254 圆桌问题
  16. Snmp4j编程简介之一
  17. java复用的具体实现_Java应用架构读书笔记(6):实现复用
  18. 3.26 文字工具的使用 [原创Ps教程]
  19. 【2014】手机卡关于怎么剪 让我告诉你
  20. Java发送SMS短信

热门文章

  1. oracle字符串转in方法,Oracle 逗号分割的字符串转换为可放入in的语句
  2. android 自定义弹窗,Android自定义弹窗
  3. nt是linux指令吗,linux shell 指令 诸如-d, -f, -e之类的判断表达式简介
  4. java从尾到头打印链表数据_Java编程实现从尾到头打印链表代码实例
  5. matlab pdist函数官方详解
  6. apply筛选 pandas_Pandas中第二好用的函数 | 优雅的apply
  7. linux halt函数,常用Linux命令 reboot halt shutdown passwd vlock exit等
  8. python 列表表达式 if_python中if else如何判断表达式成立?
  9. 以太坊白皮书_区块链60讲第33集~什么是以太坊?
  10. Andorid中的HAL