Android操作系统的底层数据传输形式是简单的字节序列形式进行传递。用通俗的话说就是系统不认识对象,只认识字节序列。而我们为了达到通信或者存储的目的,需要先将数据序列化传递,要使用时再进行反序列化还原。

Android中有2种方式可以实现序列化和反序列化:

  1. Serializable:Java自带的接口,实现该接口就可以将对象序列化。
  2. Parcelable:Android独有的接口,性能优于Serializable。原理是将一个完整的对象进行分解(拍扁),分解后的每一部分都是Intent所支持的数据类型。

二者区别是什么呢?

  • Serializable使用IO读写将序列化对象存储在硬盘上,读写速度慢;序列化过程中使用了反射技术所以会产生很多临时对象,占用空间大。但是它的优点是编码方便,开发者只需要实现Serializeable,对象就拥有了序列化和反序列化能力。
  • Parcelable是直接再内存中进行读写,内存读写速度优于硬盘读写,所以这种方式的性能比Serializable高,缺点是编码比Serializable方式更麻烦。

使用选择

  • 如果仅仅是在内存中使用,比如Activity、Service间传递信息,那强烈建议使用Parcelable,因为Parcelable比Serializable性能高,并且Serializable在序列化时会产生大量临时变量从而引起频繁GC。
  • 如果是持久化操作,推荐使用Serializable,虽然效率比较低但是因为再外界有变化的情况下,Parcelable不能很好的保存数据的持续性。

为什么Android中进程之间的复杂数据类型传递需要序列化

我们知道Android系统是基于Linux系统实现的,而Linux有进程隔离的机制。而进程如果传递复杂数据类型那传递的是对象的引用,本质上就是一个内存地址。但是传递内存地址的方式在跨进程中明显不行,由于Linux采用了虚拟内存机制,两个进程都有自己独立的内存地址空间,所以把A进程中某个对象的内存地址传递给B进程,这个内存地址在两个进程中映射到的物理内存地址并不是同一个,所以就得依靠上述的序列化手段来将对象的字节序列传递才能实现通信。而对于基本数据类型,只需要通过IPC通信不断复制达到目标进程即可。

Parcel用于IPC

Container for a message (data and object references) that can be sent through an IBinder. A Parcel can
contain both flattened data that will be unflattened on the other side of the IPC (using the various
methods here for writing specific types, or the general Parcelable interface), and references to
live IBinder objects that will result in the other side receiving a proxy IBinder connected with the
original IBinder in the Parcel.
Parcel is not a general-purpose serialization mechanism. This class (and the corresponding Parcelable API
for placing arbitrary objects into a Parcel) is designed as a high-performance IPC transport. As such,
it is not appropriate to place any Parcel data in to persistent storage: changes in the underlying
implementation of any of the data in the Parcel can render older data unreadable.

Parcel是盛放消息的容器,是接住Binder机制来进行数据传输的。它可以携带序列化后的数据通过IPC传输后在目的端进行反序列化。

Parcel也可以传递IBinder对象,在目的端将接受到传输的IBinder对象的代理。

Parcel不适合用于持久性存储,因为Parcel中任何数据的基础实现的更改都可能导致旧值不可用。并且其是在内存中实现,内存中持久化数据不可靠。

  • 从Android系统层面来说,Android系统中的Binder机制实现的IPC就使用Parcel类来进行客户端与服务端的数据交互。并且在Java层和cpp层都实现了Parcel(通过JNI关联)。由于它在c/cpp中直接使用了内存来读取数据,因此效率更高。
  • 从存储的角度来说,Parcel只是一块连续的内存。会根据需要自动扩展大小。

Parcel传输数据类型:

基本数据类型: 借助Parcel->writePrimitives()将基本数据类型从用户空间(源进程)copy到kernel空间(Binder驱动中)再写回用户空间(目标进程,binder驱动负责寻找目标进程)

复杂数据类型: 将经过序列化的数据借助Parcel->writeParcelable()/writeSerializable()从用户空间(源进程)copy到kernel空间(binder驱动中)再写回用户空间(目标进程,binder驱动负责寻找目标进程),然后再进行反序列化。

大数据: 通过Parcel->writeFileDescriptor()通过Binder传递匿名共享内存(Ashmem)的FileDescriptor从而达到传递匿名共享内存的方式,即传递的是FileDescriptor而不是真正的大数据。参考Android 匿名共享内存的使用

IBinder对象: 通过调用Parcel->writeStrongBinder(),经由kernel binder驱动专门处理来完成IBinder传递。目标进程收到的是IBinder对象的代理。

Android序列化之Parcel相关推荐

  1. 探索Android中的Parcel机制(上)

    一.先从Serialize说起 我们都知道JAVA中的Serialize机制,译成串行化.序列化--,其作用是能将数据对象存入字节流其中,在须要时又一次生成对象.主要应用是利用外部存储设备保存对象状态 ...

  2. Android序列化:Serializable Parcelable

    原文出处:http://blog.csdn.net/jdsjlzx/article/details/51122109?locationNum=14&fps=1 对于Parcel的理解: 在An ...

  3. Android序列化与反序列化

    1. 什么是java序列化,如何实现java序列化? 我们有时候将一个java对象变成字节流的形式传出去或者从一个字节流中恢复成一个java对象,例如,要将java对象存储到硬盘或者传送给网络上的其他 ...

  4. 探索Android中的Parcel机制(上) .

    一.先从Serialize说起 我们都知道JAVA中的Serialize机制,译成串行化.序列化--,其作用是能将数据对象存入字节流当中,在需要时重新生成对象.主要应用是利用外部存储设备保存对象状态, ...

  5. Android | 序列化Serializable/Parcelable 使用总结

    本文已同步发表于我的微信公众号,搜索 代码说 即可关注,欢迎与我沟通交流. 文章目录 一.什么是序列化?为什么要序列化?怎么进行序列化? 二.Serializable 2.1 序列化举例 2.2 重写 ...

  6. android对象序列化,Android序列化总结

    前言 公园里,一位仙风鹤骨的老者在打太极,一招一式都仙气十足,一个年轻人走过去:"大爷,太极这玩意儿花拳绣腿,你练它干啥?"老者淡淡一笑:"年轻人,你还没有领悟到太极的真 ...

  7. Android序列化经典解析(三)-拨乱反正,堪比窦娥的Serializable

    关于网上很多博客提到Parcelable比Serializable快,原因大致有两种说法: Serializable基于反射来做的 Serializable基于磁盘进行序列化,而Parcel基于内存 ...

  8. Android序列化(二) 之 Parcelable

    1 简介 在Android组件间或者跨进程组件间要传递数据都是通过使用 Intent.putExtra() 或者 Bundle.putXXXExtra()方法进行,这些方法无法支持传递对象的引用,而只 ...

  9. 探索Android中的Parcel机制(下)

    上一篇中我们透过源码看到了Parcel背后的机制,本质上把它当成一个Serialize就可以了,只是它是在内存中完成的序列化和反序列化,利用的是连续的内存空间,因此会更加高效. 我们接下来要说的是Pa ...

  10. android序列化讲解

    序列化在android中使用的频率非常高,尤其是在intent传递对象的时候.学习序列化非常有必要,在android中有二种序列化方式: 1.实现Serializable接口 2.实现Parcelab ...

最新文章

  1. Mongo、Redis、Memcached对比及知识总结
  2. ALTER PROFILE DEFAULT LIMIT PASS_LIFE_TIME UNLIMITED
  3. 一文看懂集成学习(详解 bagging、boosting 以及他们的4点区别)
  4. VCS user guide读书笔记启发篇
  5. HTML5入门之新的选择器
  6. Java黑皮书课后题第8章:**8.6(代数:两个矩阵相乘)编写两个矩阵相乘的方法。编写一个测试程序,提示用户输入两个3*3的矩阵,然后显示它们的乘积
  7. 报错org.apache.htrace htrace-core4 4.1.0 incubating htrace-core4.jar 报错spark
  8. linux kernel and user space通信机制,Linux内核空间与用户空间通信机制地研究.doc
  9. spring security:第一个程序解析
  10. java 异常 理解_java异常理解(1)
  11. 一个大数据量表访问优化--联动下拉框查询优化
  12. BZOJ 4518: [Sdoi2016]征途 [斜率优化DP]
  13. vue引入全局静态变量_vue-cli4 全面配置(持续更新)
  14. 电信业务分类目录2019_2019年7月国内增值电信业务许可情况分析报告:本期重点介绍内容分发网络业务...
  15. extract-text-webpack-plugin---webpack插件
  16. IDEA如何导入MySQL驱动
  17. 【一千个论文合集】计算机科学的26个细分领域近年必读论文集合
  18. 雅可比矩阵(Jacobian)、海森矩阵(Hessian)
  19. 算法竞赛入门经典(刘汝佳)——常用STL数据结构总结
  20. 浏览器市场占有率最新分析

热门文章

  1. 前端实现旗帜飘动效果系列 (Ⅳ):webgl实现
  2. 云服务器的部署形式之一私有云介绍
  3. 《操作系统》之进程、线程、同步、死锁
  4. 第12篇:给任意java程序挂Socks5代理方法
  5. python爬虫——爬取豆瓣top250电影信息
  6. Flash 101-第1部分:锤子和凿子
  7. Widows Git SSH
  8. uni-app开发桌面应用
  9. 我的世界服务器如何做无限箱子,我的世界无限箱子制作方法图文攻略
  10. 20190826——python对象实例搬家具