概念介绍:
Seralizable接口和Parcelable接口可以完成对象的序列化过程,当我们需要通过Intent和Binder传输数据时就需要使用Parcelable或者Seralizable。还有的时候我们需要把对象持久化到存储设备上或者通过网络传输给其他客户端,这个时候也需要Seralizable来完成对象的持久化。
一:Seralizable接口
Seralizable是Java所提供的一个序列化接口,他是一个空接口,为对象提供标准的序列化与反序列化操作。使用Seralizable接口很简单,只需要这个类实现Seralizable接口并声明一个serialVersionUID即可,实际上,这个serialVersoinUID也不是必须的,我们不声明这个serialVersionUID也可以实现序列化,但是这将会对反序列化过程产生影响。那到底有什么用呢。原则上序列化后的数据中的serialVersionUID只有和当前类的serialVersionUID相同才能成功的被反序列化,否则的话会报错。
public class User implements Serializable{
private static final long seralVersionUID = 519067123721295773L;
public int userId;
public String userName;
public boolean isMale;
...
}
这是一个实现Serializable接口来达到序列化。如何进行序列化与反序列化呢?
//序列化过程
User user = new User(0,"jake",true);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("cache.txt"));
out.writeObject(user);
out.close();
//反序列化过程
ObjectInputStream in = new ObjectInputStream(new FileOutputStream("cache.txt"));
User newUser = (User)in.readObject();//恢复后的newUser与user的内容完全一样
in.close();
那么那个serialVersionUID的运行机制是怎样的呢?序列化的时候会把当前类的serialVersionUID写入序列化文件中,当反序列化时系统会去检测文件中的serialVersionUID,看是否和当前类的serialVersionUID一致,如果一直就会反序列化成功,否则失败。一般的情况下我们会手动指定serialVersionUID的值,比如1L,或者让Eclipse去自动生成hash值,这样序列化和反序列化的serialVersionUID的值是相同的,如果不指定serialVersionUID的值,反序列化的时候当前类有所改变,比如增加或删除了某些属性,导致当前类的serialVersionUID与序列化文件中的serialVersionUID不一致,就会报错。
二:Parcelable接口
public class User implements Parcelable {
public int userId;
public String userName;
public boolean isMale;
public Book book;
public User(int userId,String userName,boolean isMale){
this.userId = userId;
this.userName = userName;
this.isMale = isMale;
}
@Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
@Override
public void writeToParcel(Parcel out, int flags) {
// TODO Auto-generated method stub
out.writeInt(userId);
out.writeString(userName);
out.writeInt(isMale?1:0);
out.writeParcelable(book, 0);
}
public static final Parcelable.Creator<User> CREATOR = new Creator<User>() {
@Override
public User[] newArray(int size) {
// TODO Auto-generated method stub
return new User[size];
}
@Override
public User createFromParcel(Parcel in) {
// TODO Auto-generated method stub
return new User(in);
}
};
public User(Parcel in) {
// TODO Auto-generated constructor stub
userId = in.readInt();
userName = in.readString();
isMale = in.readInt() == 1;
book = in.readParcelable(Thread.currentThread().getContextClassLoader());
}
}
序列化功能由writeToParcel方法来完成,反序列化有CREATOR来完成。