Serializable 接口
Serializable 是java 提供的一个序列化接口,它是一个空接口,为对象提供序列化和反序列化操作。使用Serializable 实现序列化相当简单,只需要在类的声明中指定一个类似下面的标识即可自动实现默认的序列化过程。
private static final long serialVersionUID=8711368828010083044
当然 ,serialVersionUID 也不是必须的,只是有可能会影响反序列化,具体影响后面分析!
//序列化
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 FileInputStream("cache.txt"));
User newUser=(User)in.readObject();
in.close();
上述代码演示了采用Serializable 方式序列化对象的典型过程,很简单!只需要把实现了Serializable接口的User对象写到文件中就可以快速恢复了,恢复后的对象newUser和user内容完全一样,但是两者并不是同一个对象!
前面提到serialVersionUID 要不要指定呢?系统既然提供了这个,那么必须是有用的。这个serialVersionUID 是用来辅助序列化和反序列化过程的,原则上序列化后的数据中 serialVersionUID 只有和当前类的serialVersionUID 相同才能够正常的被反序列化。当然这是在SDK小于24下才需要去关心这个serialVersionUID 。SDK大于24的版本 已经私有化这个常量了!都是系统自动匹配计算hash的!
Parcelable 接口
import android.os.Parcel;
import android.os.Parcelable;
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 dest, int flags) {
dest.writeInt(userId);
dest.writeString(userName);
dest.writeByte((byte) (isMale ? 1 : 0));
}
}
这里先说一下Parcel,Parcel内部包装了可序列化的数据,可以在Binder中自由传输。从上述代码可知:序列化是通过writeToParcel方法来完成的;反序列化功能由Creator完成的,内部标明了如何创建序列化对象和数组并通过Parcel的一些了read方法完成反序列过程。
Parcelable 和Serializable 的区别
既然两者都能实现序列话并且都可用于Intent间的数据传递,那么二者如何选取呢?
- Serializable 是java 中的序列化接口,其使用起来简单但是开销很大,序列化和反序列化过程需要大量I/O操作。而Parcelable 是Android 中的序列化方式,因此更适合Android 平台,它的缺点是使用起来稍微麻烦点,但是它的效率很高,这是Android推荐使用的序列化方式,因此我们首选Parcelable。Parcelable 主要用在内存序列化上,通过Parcelable 将对象序列化到存储设备中或者将对象序列化后通过网络传输也都是可以的,但是这个过程稍显复杂,因此在这两种情况下建议大家使用Serializable。