为什么我们需要序列化
序列化的原因基本可以归纳为以下三种情况:
1.永久性保存对象,保存对象的字节序列到本地文件中;
2.对象在网络中传递;
3.对象在IPC间传递。
android序列化方式
- Java 通过实现Serializable的接口来实现序列化。
- Android 原生序列化接口中Parcelable接口。
两者之间的区别
- 内存序列化 Serializable在序列化的时候会产生大量的碎片的临时变量,从而引起频繁的内存GC,相比Parcelable 更适合在内存中作为序列化传输数据。
- 网络序列化以及硬盘序列化 不能能使用在要将数据存储在磁盘上的情况(如:永久性保存对象,保存对象的字节序列到本地文件中),因为Parcel本质上为了更好的实现对象在IPC间传递,并不是一个通用的序列化机制,当改变任何Parcel中数据的底层实现都可能导致之前的数据不可读取,所以此时还是建议使用Serializable 。
Serializable实现以及使用
android使用Serializable来序列化非常的简单, 只需要实现Serializable接口, 剩下系统变自动会完成。
唯一需要注意的是serialVersionUID 序列化的版本编号,Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体(类)的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。
Parcelable实现以及使用
相比Serializable来说 Parcelable的实现比较的复杂。
- 实现Parcelable接口
- 重写writeToParcel方法,将你的对象序列化为一个Parcel对象,即:将类的数据写入外部提供的Parcel中,打包需要传递的数据到Parcel容器保存,以便从Parcel容器获取数据。
- 重写describeContents方法,内容接口描述,默认返回0即可。
- 实例化静态内部对象CREATOR实现接口Parcelable.Creator 。
- 注意:若将Parcel看成是一个流,则先通过writeToParcel把对象写到流里面,再通过createFromParcel从流里读取对象,因此类实现的写入顺序和读出顺序必须一致。*
FAQ :当项目中使用的时候 出现的一个错误: 传递对象列表,具体代码如下: 需要注意的是,若List personList = new ArrayList();则会报错,因为下面调用的putParcelableArrayList()函数其中一个参数的类型为ArrayList。 所以变量应该声明为ArrayList即可。
// parcelable对象List传递方法
public void setParcelableListMethod() {
ArrayList<Person> personList = new ArrayList<Person>();
Person person1 = new Person();
person1.setmName("王海康");
person1.setmSex("男");
person1.setmAge(45);
personList.add(person1);
Person person2 = new Person();
person2.setmName("薛岳");
person2.setmSex("男");
person2.setmAge(15);
personList.add(person2);
Intent intent = new Intent(this, PersonTest.class);
Bundle bundle = new Bundle();
bundle.putParcelableArrayList(PAR_LIST_KEY, personList);
intent.putExtras(bundle);
startActivity(intent);
}
// parcelable对象获取方法
public ArrayList<Person> getParcelableMethod(){
ArrayList<Person> mPersonList = getIntent().getParcelableExtra(PAR_LIST_KEY);
return mPersonList;
}