【齐天的博客】转载请注明出处(万分感谢!):
https://blog.csdn.net/qijinglai/article/details/80813423
前言
Android中要实现对象持久化或者对象传输就一定会用到对象序列化的操作,Android中实现序列化的方式有两种,一种是实现Java中的Serializable接口,另一种是实现Android中的Parcelable接口。当然,既然Android专门提供了序列化接口,那么一定是Parcelable的效率会更高一点。下面我们分析一下这两种方式。
Serializable
它是Java提供的一个空接口,提供对象标准的序列化和反序列化操作,使用极简单。
使用
只需实现Serializable接口即可,可选择声明或不声明serialVersionUID,区别后面会说。
如何实现序列化和反序列化
//序列化
UserBean user = new UserBean();
ObjectOutputStream out = new ObjectOutputStream(
new FileOutputStream("cache.txt"));
out.writeObject(user);
out.close();
//反序列化
ObjectInputStream in =new ObjectInputStream(
new FileInputStream("cache.txt"));
UserBean newUser = (UserBean) in.readObject();
in.close();
serialVersionUID
原则上序列化后的数据要和当前类有相同的serialVersionUID,才能正常被反序列化。
工作机制
- 序列化时会把serialVersionUID也一起写入
- 反序列化时检测serialVersionUID是否一致
·若一致,则反序列化成功
·不一致,说明类发生了某种变化(如:变量少了一两个,变量多了一两个等等)
例子
当版本升级后,我们可能删除了某几个成员变量,这时候如果是制定了serialVersionUID我们就依然可以反序列化成功,使程序最大限度的恢复数据。
但是如果有毁灭性的改变,比如修改了类名,这样就完全不可能被反序列化了。
Parcelable
只要实现这个接口的类的对象,就可以实现序列化,并可以通过Intent和Binder传递。
public class User implements Parcelable{
private int userId;
private String userName;
private boolean isMale;
private Book book;
public User(int userId, String userName, boolean isMale) {
this.userId = userId;
this.userName = userName;
this.isMale = isMale;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeInt(userId);
parcel.writeString(userName);
parcel.writeInt(isMale?1:0);
parcel.writeParcelable(book,0);
}
public static final Creator<User> CREATOR = new Creator<User>() {
@Override
public User createFromParcel(Parcel in) {
return new User(in);
}
@Override
public User[] newArray(int size) {
return new User[size];
}
};
protected User(Parcel in) {
userId=in.readInt();
userName=in.readString();
isMale=in.readInt()==1;
book=in.readParcelable(Thread.currentThread().getContextClassLoader());
}
}
模式都一样,这里只单独说一下Parcel,Parcel内部包装了可序列化的程序,可以再Binder中自由传输,在以后的IPC通信中将会用到。
总结
- Serializable是Java中的接口,使用简单,但内部需要大量的IO操作,开销很大。
- Parcelable是Android中的接口,使用麻烦,但效率很高
所以Android中首选Parcelable。Parcelable主要应用于在内存序列化上,但在存储设备及网络传输序列化时会显得太复杂,因此这两种情况使用Serilaizable会更好一些。