序列化
将数据结构或对象转换成二进制串的过程。主要用于网络传输,数据持久化,一般序列化也称为编码(Encode)。
反序列化
几种常见的序列化和反序列化协议
Serializable接口
Serializable是java提供的序列化接口,是一个空接口,仅做标记,标记该类可以被 ObjectOutputStream 序列化,以及被 ObjectInputStream 反序列化。
一个实现序列化的类,它的子类也是可序列化的。
serialVersionUID
序列化版本Uid,用来表示不同版本间的兼容性,每个类都有一个serialVersionUID,默认是Hashcode值,为了在反序列化时,确保类版本的兼容性,最好在每个要序列化的类中加入 serialVersionUID这个属性,具体数值自己定义。这样,即使某个类在与之对应的对象已经序列化出去后做了修改,该对象依然可以被正确反序列化。否则会造成对象的反序列化因为类版本不兼容而失败,报InvalidClassException。
Serializable实现原理
Serializable 的序列化与反序列化分别通过 ObjectOutputStream 和 ObjectInputStream 进行。
ObjectOutputStream.writeObject(),传入需要序列化的对象,调用writeObject0()。
一般会走到这个方法ObjectOutputStream.writeObject0()
ObjectOutputStream.writeOrdinaryObject(),将“普通”(即,不是字符串、类、ObjectStreamClass、数组或枚举常量)可序列化对象的表示形式写入流。
最终写序列化的方法
Parcelable接口
parcelable是Android提供的序列化接口,效率比较高,它是基于内存的,由于内存读写速度高于硬盘,因此Android中的跨进程对象的传递一般使用Parcelable。Parcelable实现原理是Binder,Parcelable会将数据包装成Parcel对象,然后在Binder中传输,也就是夸进程传输数据。
Parcel提供了一套机制,可以将序列化之后的数据写入到一个共享内存中,其他进程通过 Parcel可以从这块共享内存中读出字节流,并反序列化成对象,下图是这个过程的模型。
Parcel可以包含原始数据类型(用各种对应的方法写入,比如writeInt(),writeFloat()等),可以包含 Parcelable对象,它还包含了一个活动的IBinder对象的引用,这个引用导致另一端接收到一个指向这个IBinder的代理IBinder。 Parcelable通过Parcel实现了read和write的方法,从而实现序列化和反序列化。
Android中Intent/Bundle的通信原理及大小限制?
Intent 中的 Bundle 是使用 Binder 机制进行数据传送的。能使用的 Binder 的缓冲区是有大小限制的(有些手机是 2 M),而一个进程默认有 16 个 Binder 线程,所以一个线程能占用的缓冲区就更小了( 有人以前做过测试,大约一个线程可以占用 128 KB)。