重走安卓进阶路——序列化

2020-08-06  本文已影响0人  小呀么小黄鸡

序列化与反序列化是跨线程甚至跨进程通信非常重要的一个环节,它让不同类型的数据通过同一种方式传输成为可能。

序列化,把数据结构转换成可以存储的或者传输的数据格式(二进制串)的一个过程,反序列化的过程则相反。

场景:1. 数据持久化 2. 网络传输、进程间通信(AMS也是跨进程的)3. 序列化对象只针对变量,不针对方法

常见的序列化方式:JSON、XML、Serializable和Parcelable。

Serializable接口(Java)

Java提供的空接口,为对象提供标准的序列化与反序列化功能。

其中的SerialVersionUID是用来标记准备进行序列化的类的版本,在常规性的改变(增加或删除成员变量)时,只要指定的是相同的serialVersionUID仍可序列化成功。非常规性改变:修改了类名,修改了成员变量的类型。

serialVersionUID的详细工作机制是这样的:序列化的时候系统会把当前类的serialVersionUID写入序列化的文件中(也可能是其他中介),当反序列化的时候系统会去监测文件中的serialVersionUID,看它是否和当前类的serialVersionUID一致,如果一致则说明序列化的类的版本和当前类的版本是相同的,这个时候可以成功反序列化;否则就说明当前类和序列化的类相比发生了某些变换,如变量的数量、类型发生了改变,这是无法正常反序列化,因此会报InvalidClassException。

ps.静态成员变量属于类不属于对象,所以不会参与序列化,成员变量用transient标记也不参与序列化。

Parcelable接口(Android)

Parcelable也是一个接口,只要实现这个接口,一个类的对象就可以实现序列化并可以通过Intent和Binder传递。

其中的方法

createFromParcel(Parcel in),从序列化后的对象中创建原始对象;

newArray(int size),创建指定长度的原始对象数组;

writeToParcel(Parcel out, int flags),将当前对象写入序列化结构中,起哄flags标识有两种值:1标识当前对象需要作为返回值返回,不能立即释放资源,几乎所有情况都用0;

describeContents,返回当前对象的内容描述,如果含有文件描述符,返回1,否则返回0,几乎所有情况都返回0

安卓系统已经为我们提供了许多实现了Parcelable接口的类,它们都是可以直接序列化的,比如Intent、Bundle、Bitmap等,同时List和Map也可以序列化,前提是它们里面每个元素都是可以序列化的。

Serializable和Parcelable都能实现序列化,该选谁呢?

serializable是Java中的序列化接口,其使用起来简单但是开销很大,序列化和反序列化过程需要大量I/O操作。而Parcelable是Android中的序列化方式,因此更适合用在Android平台上,它的缺点就是使用起来稍微麻烦点,但是它的效率很高,所以我们要首选Parcelable。

Parcelable主要用在内存序列化上,通过Parcelable将对象序列化到存储设备中或者将对象序列化后通过网络传输也都是可以的,但是这个过程会稍显复杂,因此在这两种情况下建议大家使用Serializable。

阿里的fastjason(Weex)

我们在weex中使用的序列化方式是json,而fastjson是weex中使用的序列化库,我对它的理解和各位一样,是通过一些文章的指引,其中对我帮助最大的是这一篇——

Android学习笔记之Fast Json的使用 https://www.cnblogs.com/RGogoing/p/5245098.html

作者对Serializable和Parcelable也有一篇文章,大家也可以看看。

Android序列化之Serializable和Parcelable https://www.cnblogs.com/RGogoing/p/5209516.html

文章主要讲述了fastjson使用的四个要点:

1.什么是Fast Json

2.如何使用Fast Json

3.Fast Json的相关原理

4.Fast Json的优势,以及为什么推荐使用Fast Json

其中第4点比较吸引我,以下做一个总结:

1. 使用SerializeWriter(通过技术细节减少判断、避免多次申请内存空间以及gc的调用、善用现成缓存)

2.使用asm来避免反射机制的使用 java字节码框架ASM

3.使用IdentityHashMap去优化性能(而不是ConcurrentHashMap,减少了transfer的消耗,保证线程安全的同时达成并发)

4.Deserializer的主要优化算法(基于预测的词法分析方式,加快反序列化)

5.Sort field fast match算法(在封装和解析的时候都是默认使用这个算法的,就是以有序的方式将Json 字符串进行保存,如果数据保存的形式是有序的,那么就使用优化算法,不用对每一个token进行处理)【其实就是满足已知结构就不用存储符号】ps.token指的是通过类似split的Deserializer优化算法后得到的json字符块

可见,fastjson确实花了很多精力在反序列化的解析上,以期提高解析的效率。

XML的序列化方式我在平常很少用到,也就不班门弄斧了,希望对各位有帮助。

上一篇下一篇

猜你喜欢

热点阅读