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;
}
public int describeContents(){
return 0;
}
public void writeToParcel(Parcel out,int flags){
out.writeInt(userId);
out.writeString(userName);
out.writeInt(isMale ? 1 : 0);
out.writeParcelable(book,0);
}
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中自由传输。上述代码中,在序列化过程中需要实现的功能有序列化、反序列化和内容描述。序列化功能由writeToParcel方法来完成,最终是通过Parcel中的一系列wirte方法来完成的;反序列化由CREATOR来完成,其内部标明了如何创建序列化对象和数组,并通过Parcel的一系列read方法来完成反序列化;内容描述由descirbeContents方法来完成,几乎在所有情况下这个方法都应该返回0,只有当前对象中存在文件描述符时,返回1。注:在User(Parcel in)方法中,由于book是另一个可序列化对象,所以它的反序列化过程需要传递当前线程的上下文类加载器,否则会报无法找到类的错误。
系统已经为我们提供了许多实现了Parcelable接口的类,它们都是可以直接序列化的,比如Intent,Bundle,Bitmap等。同时List和Map也可以序列化,前提是它们里面的每个元素都是可序列化的。
既然Parcelable和Serializable都能实现序列化并且都可用于Intent间的数据传递,那么二者该如何选取呢?Serializable是Java中的序列化接口,其使用起来简单但是开销很大,序列化与反序列化过程需要大量I/O操作。而Parcelable是Android中的序列化方式,更适合用在Android平台上,它的缺点就是使用稍微麻烦,但是效率很高,这是Android推荐的序列化方式,因此我们要首选Parcelable。Parcelable主要用在内存序列化上,通过Parcelable将对象序列化到存储设备或者将对象序列化后通过网络传输也都是可以的,但是这个过程会稍显复杂,建议Serializable。以上就是Parcelable和Serializable的区别。