前言
本文为学习《Android开发艺术探索》时加深学习印象所写。
Android开发时经常会使用到Intent和Binder,如果需要传输数据那么传输对象就需要实现Serializbale或Parcelable,以下就主要探讨Serializbale和Parcelable是如何实现序列化以及它们的区别。
1、Serializbale
Serializbale 是java所提供的一个序列化接口,它是一个空接口,为对象提供标准的序列化和反序列化操作。
使用非常简单只要实现Serializbale即可,如下所示:
public class User implements Serializable {
public int userId;
public String userName;
public boolean isMale;
}
进行对象的序列化与反序列化也很简单
User user = new User();
//序列化
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("cache.txt"));
out.writeObject(user);
out.close();
//反序列化
ObjectInputStream in = new ObjectInputStream(new FileInputStream("cache.txt"));
User newUser = (User)in.readObject();
in.close();
上述代码是Serializbale序列化方式的一种,将User对象写到文件中,恢复后得到newUser,两个虽然内容相同但是并不是同一个对象。
Serializbale 还可以指定一个serialVersionUID(一下简称UID);它是用来辅助序列化和反序列化过程的,原则上序列化数据中的UID要和当前类的UID相同才能够正常的被反序列化。 如果不指定系统会将当前类的hash值并赋值给UID,这样的话一个类如果添加或删除了成员变量将会导致UID被改变,反序列化时就会失败。所以指定UID可以帮助我们避免反序列化导致的carsh,提升项目稳定性。
2、Parcelable
Parcelable 是Android提供的序列化接口,实现起来要相对麻烦一些。 如下:
public class User implements Parcelable {
public int userId;
public String userName;
public boolean isMale;
protected User(Parcel in) {
userId = in.readInt();
userName = in.readString();
isMale = in.readByte() != 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];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeInt(userId);
parcel.writeString(userName);
parcel.writeByte((byte) (isMale ? 1 : 0));
}
}
可以看到 Parcelable是将数据写到Parcel,通过Parcel序列化数据从而进行传输。通过CREATOR来反序列化。Parcelable的序列化在内存中就能完成。
3、区别及选择
两者最大的区别是Serializbale存储在硬盘上,Parcelable存储在内存中。内存的读写效率肯定比硬盘高的多,因此在Android中进行数据传递推荐使用Parcelable。如果需要保存到硬盘或者长时间存储的推荐使用Serializbale。