Android中Serializable和Parcelable的用法及区别
第一点,解释什么是序列化。
序列化 (Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程。
在序列化期间,对象将其当前状态写入到Ram 或者是rom,也就是临时或持久性存储区。
以后,可以通过从存储区中读取对象的状态,重新创建该对象,这个就是反序列化。
Android中用到的序列化有两种方法,第一种是Serializable,第二种是Parcelable。
Serializable
Serializable 是可串行化,也就是序列化的意思。Serializable 是java序列化的一种方式,在java里面也是一个接口。源码里面这个接口里啥也没有,如果一个接口里面什么内容都没有,那么这个接口是一个标识接口就相当于告诉JVM,需要你帮我序列化这个类。
怎么去实现它呢?就把我们要序列化的类继承这个接口就行了,最好再指定一个
serialVersionUid
这个serialVersionUID是用来辅助对象的序列化与反序列化的,原则上序列化后的数据当中的serialVersionUID与当前类当中的serialVersionUID一致,那么该对象才能被反序列化成功。这个serialVersionUID的详细的工作机制是:在序列化的时候系统将serialVersionUID写入到序列化的文件中去,当反序列化的时候系统会先去检测文件中的serialVersionUID是否跟当前的文件的serialVersionUID是否一致,如果一直则反序列化成功,否则就说明当前类跟序列化后的类发生了变化,比如是成员变量的数量或者是类型发生了变化,那么在反序列化时就会发生crash,并且回报出错误
也可以不指定~不指定就会随机分配一个。
两者最大的区别在于存储媒介的不同,Serializable使用IO读写存储在硬盘上,而Parcelable是直接在内存中读写,很明显内存的读写速度通常大于IO读写,所以在Android中通常优先选择Parcelable。
Serializable 使用硬盘存储的性质也就注定了它一般用于异地网络传输。
序列化过程使用了反射技术,并且期间产生临时对象。优点代码少。是利用反射创建了一个对象,调用该类的第一个非Serializable类型的父类的无参构造方法。所以这就是为什么通过反序列化创建对象的时候,并不会执行被序列化对象的构造方法。对于实现Serializable接口的类,并不要求该类具有一个无参的构造方法, 因为在反序列化的过程中实际上是去其继承树上找到一个没有实现Serializable接口的父类(最终会找到Object),然后构造该类的对象,再逐层往下的去设置各个可以反序列化的属性(也就是没有被transient修饰的非静态属性)。
Parcel
简单来说,Parcel提供了一套机制,可以将序列化之后的数据写入到一个共享内存中,其他进程通过Parcel可以从这块共享内存中读出字节流,并反序列化成对象。
实现方法:继承Parcelable,重写3个方法,一个静态对象
构造方法-根据parcel 构造出一个对象
重写3个方法
createFromParcel(Parcel parcel)
writeToParcel(Parcel parcel)
newArray(int size)
静态内部类 CREATOR,用于反序列化调构造出对象
本质上就是把对象的基本数据按照开发者定义的顺序写入一个parcel 中,接收端再按照这个顺序读取出来,组合成一个对象~
优点:内存中实现,快!!!不会有大量临时变量