基本概念
序列化和反序列化
序列化和反序列化是指:将一个实例对象编码成字节流,并从字节流编码中重新构建对象实例的能力。
- 序列化
将一个对象编码成字节流。 - 反序列化
从一个字节流中读出一个对象实例。 
反序列化是按照序列化写入的顺序读取的。
对象变量类型
- 序列化对象的时候只是针对变量进行序列化,不针对方法进行序列化
 - 静态成员 
static变量属于类不属于对象,所以不参与序列化过程 - 用 
transient关键字标记的成员变量不参与序列化过程 
两种方法
Java提供的SerializableAndroid提供的Parcelable
Serializable 接口
Serializable 接口是 Java 提供的一个序列化接口,它是一个空接口,为对象提供标准的序列化和反序列化操作。使用 Serializable 来实现的对象的序列化相当简单,只需要在类中指定 serialVersionUID 标识即可自动实现默认的序列化过程。
serialVersionUID
- 概念
Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体(类)的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。 - 值
根据类名、接口名、成员方法及属性等来生成一个 64 位的哈希字段。默认值是1L,但是Android强烈建议显示指定一个值。 - 生成方法
Android Studio自动生成serialVersionUID的方法:
打开Settings,切换到Editor->Inspections->Java->Serialization issues,找到Serializationzable class without ‘serialVersionUID’,将其勾选即可。或者直接搜索serialVersionUID。
鼠标放在Serializable接口的类名上,Android Studio的智能提示(智能检查),就会多出了Add ‘serialVersionUID’ field,完毕! 
示例类
MyDataSerializable 自定义可以序列化的类,内部支持集合,但是静态变量和 tansient 申明的变量是无法序列化的。
1  | public class MyDataSerializable implements Serializable {  | 
测试代码
1  | private void testSerializable(){  | 
结果分析
1  | 11:32: 6536/com.yD/:ShowIPCActivity:: testSerializable: myDataSerializable =  | 
从 Log 中可以看出:   
transient关键字
申明的变量不能序列化,反序列化的结果为0。static变量
定义为static的变量,是属于类的,全局的,实际上并不参与序列化。所以读取到的static变量值是全局数据区中的值,并不是反序列化产生的值,本例中表示改变后的值。
Parcelable 接口
Parcelable 接口是 Android SDK 提供的一种专门用于 Android 应用中对象的序列化和反序列化的方式,相比于 Seriablizable 具有更好的性能。实现 Parcelable 接口的对象就可以实现序列化并可以通过Intent 和 Binder 传递。
序列化的对象可以包含:基本数据类型,Bitmap,List,Map,IBinder等,以及所有已经实现 Parcelable 的类。
实现及重写
实现 Parcelable 的类,  Android Studio 会给出需要实现和重写的方法模板:    
1  | public static class Test implements Parcelable{  | 
- 序列化
writeToParcel表示序列化的过程,将变量都写入Parcel。 - 反序列化
readFromParcel表示反序列化的过程,从Parcel中读取并生成类对象。 describeContents
该方法通常直接返回 0 。Parcelable对象在扁平化中,如果包含文件描述符,则该值必须返回CONTENTS_FILE_DESCRIPTOR。 参考 Parcelable API
这里“空构造方法”和 readFromParcel 两个都不是必须的。反序列化也可以在 createFromParcel 中直接反序列化;但是 AIDL 中反序列化时,必须定义“空构造方法”和 readFromParcel 才能成功反序列化。所以我们最好在自定义 Parcelable 中默认实现这两个方法养成好习惯。  
反序列化是按照序列化的顺序读取的,所以
readFromParcel反序列化读取变量的值时,一定要按照writeToParcel写入的顺序读取。
示例类
1  | public class MyDataParcelable implements Parcelable {  | 
测试代码
1  | // Activity1 中初始化 MyDataParcelable, 启动 Activity2  | 
结果分析
从结果上看,复杂数据对象 MyDataParcelable 成功的被序列化后传递出去,接收后能正常的反序列化解析出来。  
1  | 16:02: 11509/com.yD/:ShowIPCActivity:: testParcelable: myDataParcelable =  | 
对比
Serializable
是Java中的序列化接口,使用起来简单但是开销大,序列化和反序列化需要大量的I/O操作。主要用于序列化到存储设备或者序列化后通过网络传输。Parcelable
是Android提供的标准序列化接口,因此更适合Android平台,缺点是使用稍微麻烦,但是效率高;主要用于内存序列化。