Android中序列化的原理与机制

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_29856589/article/details/66473299

序列化的原理:

引用Java语言程序设计-基础篇中第539页中写道:并不是所有对象都是可以序列化的(这句话说明了序列化必须要具备某种条件才可以进行序列化),因为序列化的对象是Java.Io.Serializable接口的实例。也就是说如果需要实现序列化功能必须要实现这一接口;但是序列化又能有什么用处呢?接下来我们看看源码中有什么介绍。(源码下载地址


源码中是这样说道支持IO的操作但是同时抛出IO的异常也就是说实例化这个接口后,该对象可以转换成流的操作,那么问题来了如果该对象转为一个流对象时候那我们又怎么去取得这个流对象转换为相应的流对象呢。

这时源Java开发工程师是这样子给出了一个概念:反序列化;也就是说对于已经被转换的序列化对象的对象要转为序列化对象的时候,则可通过反序列化的方法进行逆方向序列化,转为序列化对象。

说到底:序列化就是将源对象转为io,而反序列化就是讲io转为源对象,但是序列化和反序列化对应着一个key保证他们对应的源对象是一致的,使用序列化的时候必须牢记如果该对象有改变了且Key没有声明了那么反序列和序列对应的对象则不等那么反序列则不会成功。这样的好处就是讲可以保存数据的持久性增强,

序列化的种类

Android中的序列化分为两种:一种是Java自带的Serializable,另外一种是由Google工程师封装好的Parcelable

Serializable

Serializable接口是Java提供的一个序列化接口,它是一个空接口,为对象提供标准的序列化和反序列化操作。使用Serializable来实现的对象的序列化相当简单,只需要在类的声明该接口,过程非常简单,甚至都不需要声明serialVersionUID完成这个过程,但serialVersionUID需不需要指定呢?

需要!

Java API提供了这个serialVersionUID,必然它是有用的。这个serialVersionUID是用来辅助序列化和反序列化过程的,原则上序列化后的数据中的serialVersionUID只有和当前类的serialVersionUID相同才能够正常地被反序列化。

serialVersionUID原理:序列化的时候系统会把当前类的serialVersionUID(后续简称UID)写入序列化的二进制文件中,当反序列化的时候系统会检测文件中的UID是否和当前类的UID一致,一致则成功反序列化说明版本一致;不一致说明反序列化失败,不一致的原因可能有由于不指定UID而且成员变量或者属性发生改变则类中的UID会自动改变以至于不一致。

手动指定UID,可以最大程度的避免UID的不一定,这样最大程度上避免反序列化的失败,即使类中的属性成员变量发生改变,也可以最大程度上恢复数据。

如果类结构发生了非常规性改变,比如修改了类名,修改了成员变量的类型,这个时候尽管serialVersionUID验证通过了,但是反序列化过程仍然会失败,因为类的结构有了本质上的改变,无法从旧版本中还原出一个新类的结构对象。

对于使用序列化还有两点需要注意:

1.静态成员变量属于类不属于对象,所以不参与序列化过程

2.transient关键字标记的成员变量不参与序列化过程

Parcelable

AndroidSDk提供:高性能序列化支持Intent以及bundle的配合使用大大提高数据序列化的高性能,以及节约内存的使用。

代码展示:

从我插入我写好的代码图片中可以看出我声明了两个序列化的类,并对他们进行实例化,第一个Java类中的序列化,将一个类转换成一个文件后,在反序列化转为一个类,注意我分成两次反序列化,可以很清楚的看到第二次反序列化前我实例了一个新的Java序列化对象然后对原来的文件反序列结果也只是得到初始序列化对象,也就是在不发生原对象中的属性改变时候反序列可以成功执行,而且静态变量很好的可以看出是不支持序列化这一功能的实现的;在Android的序列化中,而且成员变量有statictransient的修饰符但是Android自动构建的序列化构造方法以及自动生成的方法都不支持对这两个关键字修饰的序列化作用。我使用了Pacrel但是需要注意在构造方法中如果Pacrel的角标不是初始角标的话极大程度上会读取不到数据甚至还会出现空指针异常,如果你需要指定的数据在构造方法中实例化则按照你的写入数据的顺序来指定角标初始化数据,如果是按照所有数据进行初始写入顺序一一配对,则只需指定角标为0开始就可以了。PS序列化的对比,P对于S来说性能上得到了提高数据的扩展性也得到了提高但是写法就较为复杂一些而且序列化时必须来实现Creator这个方法而且还必须指定为Public Static final这样的修饰符否则会出现异常。


阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页