不知道大家在日常开发中,对于序列化和反序列化了解有多少,之前有同事私下聊天问过我:“序列化你是怎么做的?”,我当时很自然的就说了一句:“我是用实现Serializable接口的形式实现序列化”,同事:“我记得似乎还有一种方式,通过Parcelable接口实现”,虽说没有继续探讨下去,只是简单的沟通,但是我知道是时候要总结归纳一下两者的区别了,不知道各位研发人员都是怎么实现序列化的,是否和我一样都是使用Serializable从而忽略了Parcelable。
下面进入正题首先是概念什么是序列化和反序列化
在我们进行Android开发的时候,我们都知道不能直接将对象的引用传给Activity/Fragment,我们需要将这些对象放到一个Intent或者Bundle里面,然后再传递,此时就会出现另一个问题,是直接放进去吗? 显然是不行的,此时就是序列化/反序列化问题了。
可能到这里大家就会有一个疑问为什么需要序列化?其实上面就已经有所解答,在这里总结一下。
① 永久性保存对象,保存对象的字节序列到本地文件中;
② 通过序列化对象在网络中传递对象;
③ 通过序列化在进程间传递对象。
序列化概念
简单来说,就是将不可传递的对象变为可以在Activity/Fragment之间传递的对象,即将一个对象转换成可存储/可传输的状态,序列化后的对象可以在网络上进行传输,也可以存储到本地磁盘。
反序列化概念
很简单,就是序列化的逆过程。
那么接下来就有人有疑问了,怎么样才能通过序列化就能传输对象了,也就是对象怎么成为可序列化对象?
Android中Intent大家都很熟悉,以它为例,有两种方式实现:
①:待序列化对象通过实现 Serializable 接口方式实现序列化;
②:待序列化对象通过实现 Parcelable 接口方式实现序列化;
这里简单说下两者的区别:Serializable 这个是Java自带的实现序列化的方式,而Parcelable 则是Android独有的实现序列化的方式;实现Serializable接口的对象,会被转化为流数据的形式,在进程间/网络/本地磁盘传递和存储,而实现Parcelable 接口的对象则是通过将一个完整的对象进行分解,分解后的每一部分都是Intent所支持的数据类型,这样也就实现传递对象的功能了。
这时候大家有可能就有个疑惑,我们应该怎么选择,什么时候用Serializable?什么时候用 Parcelable ?
选择序列化方法的原则:
① 在使用内存的时候,Parcelable比Serializable性能高,所以推荐使用Parcelable。
② Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC。
③ Parcelable不能使用在要将数据存储在磁盘上的情况,因为Parcelable在外界(Android版本变化)有变化的情况下,不能很好的保证数据的持续性。尽管Serializable效率低点,但此时还是建议使用Serializable 。
说了这么多概念性的东西,到底是要怎么写呢? 下面看下具体代码,大家就明白了。
实现Serializable接口:
内容很简单主要分为两步:
① 实现Serializable接口;
② 添加private static final long serialVersionUID = XXXL;
大家要问了,添加这个long型属性有什么意义? 其实很简单,就是在我们序列化与反序列化的过程中,这个属性就是保证前后对象是一个。
实现Parcelable接口:
Parcelable会复杂一些,主要步骤如下:
① 实现Parcelable接口;
② 重写describeContents()和writeToParcel()方法;
③ 创建待序列化的类的含Parcel参数的构造函数;
④ 创建Parcelable.Creator<T> CREATOR的公共常量,重写createFromParcel()和newArray()方法;
相应方法注释已在代码中体现,写到这里博文就已经接近尾声,相信大家都已经回想起这两种方式的具体实现,最后给大家总结一下。
Serializable与Parcelable最核心的区别:
对于Android开发,大家尽量使用Parcelable,毕竟追求的是速度,只有速度快了,用户体验才会好。
① 代码复杂度:
Serializable代码量少,写起来简单方便,而Parcelable代码则多一些;
② 代码执行速度:Parcelable的速度比Serializable高十倍以上;
Serializable的迷人之处在于你只需要对某个类以及它的属性实现Serializable 接口即可(某个类你想序列化它,必须保证它实现Serializable接口,同时也要保证它所包含的属性对象也是实现Serializable接口的对象)。Serializable 接口是一种标识接口(marker interface),这意味着无需实现方法,Java便会对这个对象进行高效的序列化操作。
这种方法的缺点是使用了反射,序列化的过程较慢。这种机制会在序列化的时候创建许多的临时对象,容易触发垃圾回收。Parcelable方式的实现原理是将一个完整的对象进行分解,而分解后的每一部分都是Intent所支持的数据类型,这样也就实现传递对象的功能了,速度快。
博文的最后,希望大家多多点赞支持!!!
参考博文:
https://www.jianshu.com/p/a60b609ec7e7点击打开链接