一、概述
在上一篇中我们介绍了Java中的序列化方式(也能用于Android),详情:Java Serializable(序列化),本篇继续介绍Android中特有的序列化方式:Parcelable,它也是一个接口,只要实现这个接口,一个类的对象就可以实现序列化并可以通过Intent和Binder传递。
Parcelable是Android中进行跨进程间通信传递数据的方式,它基于内存进行序列化和反序列化,因此效率较高。Parcelable定义了将数据写入Parcel,和从Parcel中读出数据的接口。一个实体(用类来表示),如果需要封装到消息中去,就必需实现这一接口。其中Parcel的作用:它提供一套机制,可以将序列化之后的数据写入到一个共享内存中,其他进程通过Parcel可以从这块共享内存中读取出字节流,并反序列化成对象。
二、Parcelable接口定义
public interface Parcelable {
// 内容描述接口,很少用到
public int describeContents();
// 序列化
public void writeToParcel(Parcel dest, int flags);
// 反序列化,目的是要从Parcel中构造一个实现了Parcelable的类的实例处理。
// 因为实现类在这里还是不可知的,所以利用模板参数,类名通过模板参数传入。
// 为了能够实现模板参数的传入,这里定义Creator嵌入接口,内含两个接口函数分别返回单个和多个继承类实例。
public interface Creator<T>
{
public T createFromParcel(Parcel source);
public T[] newArray(int size);
}
}
三、应用Parcelable
public class User implements Parcelable {
public String name;
public int age;
private User(Parcel in) {
// 按照写入的顺序依次从Parcel中恢复对象字段值
name = in.readString();
age = in.readInt();
}
public User(String name, int age) {
this.name = name;
this.age = age;
}
// 反序列化过程(从Parcel读取数据)
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;
}
// 序列化过程(将数据写入Parcel)
@Override
public void writeToParcel(Parcel dest, int flags) {
// 将各个字段按照顺序写入流中
dest.writeString(name);
dest.writeInt(age);
}
}
以下是测试Activity
public class TestActivity extends Activity {
private static final String TAG = TestActivity.class.getSimpleName();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_simple);
Parcel parcel = Parcel.obtain();
User user = new User("aronchen", 28);
//写入Parcel
parcel.writeParcelable(user, 0);
//Parcel读写共用一个位置计数,这里一定要重置一下当前的位置
parcel.setDataPosition(0);
//读取Parcel
User user1 = parcel.readParcelable(User.class.getClassLoader());
Log.e(TAG, "user.name:" + user1.name + "; user.age:" + user1.age);
}
}
可以看出,使用Parcelable接口稍微麻烦点,和Serializable相比,我们需要在writeToParcel中按序将各个字段写入到流中,同样,在createFromParcel中我们需要自己返回一个User对象。其中的CREATOR用到了代理设计模式。
三、Parcelable与Serializable的区别
Serializable | Parcelable |
Java SE、Android通用 | Android专用 |
需要大量I/O操作,效率低 | 内存序列化,效率高 |
使用较方便 | 使用较复杂 |