Learn && Live
虚度年华浮萍于世,勤学善思至死不渝
前言
Hey,欢迎阅读Connor学Android系列,这个系列记录了我的Android原理知识学习、复盘过程,欢迎各位大佬阅读斧正!原创不易,转载请注明出处:http://t.csdn.cn/Mndcr,话不多说我们马上开始!
1.Serializable接口
(1)实现Serializable接口
(2)声明serialVersionUID,实际上不声明也可以完成序列化,但可能无法完成反序列化,这一点稍后讨论
(3)保证类中的所有属性都是可序列化的(主要针对对象属性)
ByteArrayOutputStream bos = null;
ByteArrayInputStream bis = null;
ObjectOutputStream oos = null;
ObjectInputStream ois = null;
try {
// 序列化
bos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(bos);
oos.writeObject(this);
// 反序列化
bis = new ByteArrayInputStream(bos.toByteArray());
ois = new ObjectOutputStream(bis);
this = (Man) ois.readObject();
} catch(Exception e) {}
几点说明:
(1)序列化、反序列化的过程可以实现对象的深克隆
(2)静态变量属于类不属于对象,不会参加序列化过程;用transient关键字标记的成员变量也不参与序列化过程
(3)序列化时系统会把当前类的serialVersionUID写入序列化的文件中或其他中介中,当反序列化的时候系统会去检测文件中的serialVersionUID是否与当前类的一致,一致则可以完成反序列化,否则说明当前类和序列化的类相比有变化(成员变量的数量、类型),系统重新计算当前类的hashCode并赋给serialVersionUID,导致比较不一致,无法正常反序列化,程序出现crash
2.Parcelable接口
Parcelable实现
实现Parcelable接口,一个类的对象就可以实现序列化并可以通过Intent和Binder传递
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;
}
// 1
public int describeContents() {
return 0;
}
// 2
public void writeToParcel(Parcel out, int flags) {
out.writeInt(userId);
out.writeString(userName);
out.writeInt(isMale ? 1 : 0);
out.writeParcelable(book, 0);
}
// 3
public static final Parcelable.Creator<User> CREATOR = new Parcelable.Creator<User>() {
public User createFromParcel(Parcel in) {
return new User(in);
}
public User[] newArray(int size) {
return new User[size];
}
};
private User(Parcel in) {
userId = in.readInt();
userName = in.readString();
isMale = in.readInt == 1;
book = in.readParcelable(Thread.currentThread().getContextClassLoader());
}
}
Parcel内部包装了可序列化的数据,可以在Binder中自由传输。由上述代码,Parcelable序列化过程需要实现的功能有注释1、2、3处的三个方法
(1)describeContents:内容描述,几乎在所有情况下都返回0,仅当当前对象中存在文件描述符时,返回1
(2)writeToParcel:序列化,最终是通过Parcel中的write方法完成
(3)CREATOR:反序列化,声明了如何创建序列化对象和数组,通过Parcel的read方法实现
需注意:
(1)Book类的对象book也必须为实现了Parcelable接口的可序列化对象,其反序列化过程需要传递当前线程的上下文类加载器,否则报ClassNotFound
(2)系统已经提供了许多实现了Parcelable接口的类,如Intent、Bundle、Bitmap等,同时List、Map也可以序列化,前提是其内元素皆可序列化
Parcelable方法
3.Serializable与Parcelable
Serializable是java中的序列化接口,并且使用起来简单,但是开销很大,序列化和反序列化过程需要大量的I/O操作,而Pracelable是android中的序列化,更适合在android平台上,缺点是使用起来麻烦,但是它的效率高,这是android推荐的序列化方式,通过Parcelable将对象序列化到存储设备中或者将对象序列化后通过网络传输也都是可以的,但是过程稍微复杂,因此在这两种情况下建议大家使用Serializable