反序列化是将字节序列恢复为对象,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。
Android中两种序列化的方法
Serializable:这是一个Java(java.io.Serializable)的为对象提供标准的序列化和反序列化的接口。使用方式就是在类上面直接implements这个接口就行了。
在使用Serializable的时候最好加上SerialiVersionUID(序列化 版本号),当然不加的话也能正常实现序列化,但是可能会对反序列化有影响。
有什么影响?
序列化时,会把serialVersionUID写入序列化文件,如果没有显式的指定,那么编译器就会自动根据这个类进行生成一个,反序列化的时候就会检测文件中的serialVersionUID,如果和当前类的serialVersionUID不同,那么就反序列化失败。如果我们在类中增加或者减少字段了,那么自动生成的serialVersionUID肯定会不同,所以会反序列化失败。所以,为了以后扩展,最好显式的指定serialVersionUID。
在Androidstudio中生成serialVersionUID:
File–>Settings–>Editor–>Inspections–>Java–>Serialization issues–>Serializable class without ‘serialVersionUID’
或者直接Alt+Enter提示加入。
注意:
对象序列化保存的是对象的成员变量。所以对象序列化不会序列化类中的静态变量。静态变量属于类,不属于对象。
另外被transient关键字修饰的变量也不会参与序列化。
Parcelable:
android.os.Parcelable是Android提供的序列化接口,使用比Serializable稍显复杂。类实现了Parcelable接口后
还有几个默认的方法。
describeContents():返回当前对象的内容描述。返回值0或1。默认0。
newArray(int size): 原始对象数组。
createFromParcel(Parcel in):创建原始对象。
writeToParcel(Paprcel dest,int flags):将当前对象写入序列化结构。
对比:
Serializable是Java的接口使用时需要大量I/O操作,开销大。常用于持久化对象到本地,网络传输。
Parcelable效率高,使用麻烦。常用于内存级别的序列化,比如不同组件程序间的传输。
程序示例:
序列化
try {
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("Test.txt"));
out.writeObject(new Person());
out.close();
} catch (IOException e) {
e.printStackTrace();
}
反序列化:try {
ObjectInputStream in = new ObjectInputStream(new FileInputStream("Test.txt"));
Person p = (Person)in.readObject();
in.close();
} catch (IOException e) {
e.printStackTrace();
}