1. Parcel类
Parcel
主要用于在进程间通讯,传递数据。
Parcel
通过obtain()
静态方法获取,数据的存储和读取主要通过writeXXX()
和readXXX()
实现,marshall()
和unmarshall()
将数据序列化和反序列化,最后recycle()
回收资源。
public byte[] writeValue() {
Parcel data = Parcel.obtain();
try {
data.writeInt(12);
data.writeDouble(34.5);
data.writeString("This is a string");
return data.marshall();
} finally {
data.recycle();
}
}
public void readValue(byte[] bytes) {
Parcel reply = Parcel.obtain();
try {
reply.unmarshall(bytes, 0, bytes.length);
reply.setDataPosition(0);
reply.readInt();
reply.readDouble();
reply.readString();
} finally {
reply.recycle();
}
}
2. Parcelable类
Parcelable
是个接口,用于数据的传递。
在Parcel
中,存储Parcelable
数据,调用Parcelable.writeToParcel(Parcel, int)
方法。
public final void writeParcelable(Parcelable p, int parcelableFlags) {
if (p == null) {
writeString(null);
return;
}
writeParcelableCreator(p);
// Parcelable.writeToParcel方法
p.writeToParcel(this, parcelableFlags);
}
而读取Parcelable
数据时,调用Creator
的子类,并调用createFromParcel()
方法来读取
public final <T extends Parcelable> T readParcelable(ClassLoader loader) {
// 获得Parcelable中的CREATOR类
Parcelable.Creator<?> creator = readParcelableCreator(loader);
if (creator == null) {
return null;
}
if (creator instanceof Parcelable.ClassLoaderCreator<?>) {
Parcelable.ClassLoaderCreator<?> classLoaderCreator =
(Parcelable.ClassLoaderCreator<?>) creator;
return (T) classLoaderCreator.createFromParcel(this, loader);
}
return (T) creator.createFromParcel(this);
}
public final Parcelable.Creator<?> readParcelableCreator(ClassLoader loader) {
String name = readString();
if (name == null) {
return null;
}
Parcelable.Creator<?> creator;
synchronized (mCreators) {
HashMap<String,Parcelable.Creator<?>> map = mCreators.get(loader);
if (map == null) {
map = new HashMap<>();
mCreators.put(loader, map);
}
// 如果有缓存,直接读取create
creator = map.get(name);
if (creator == null) {
try {
// If loader == null, explicitly emulate Class.forName(String) "caller
// classloader" behavior.
ClassLoader parcelableClassLoader =
(loader == null ? getClass().getClassLoader() : loader);
// Avoid initializing the Parcelable class until we know it implements
// Parcelable and has the necessary CREATOR field. http://b/1171613.
Class<?> parcelableClass = Class.forName(name, false /* initialize */,
parcelableClassLoader);
if (!Parcelable.class.isAssignableFrom(parcelableClass)) {
throw new BadParcelableException("Parcelable protocol requires that the "
+ "class implements Parcelable");
}
// 查看是否存在名字为CREATOR的静态属性
Field f = parcelableClass.getField("CREATOR");
if ((f.getModifiers() & Modifier.STATIC) == 0) {
throw new BadParcelableException("Parcelable protocol requires "
+ "the CREATOR object to be static on class " + name);
}
Class<?> creatorType = f.getType();
if (!Parcelable.Creator.class.isAssignableFrom(creatorType)) {
// Fail before calling Field.get(), not after, to avoid initializing
// parcelableClass unnecessarily.
throw new BadParcelableException("Parcelable protocol requires a "
+ "Parcelable.Creator object called "
+ "CREATOR on class " + name);
}
creator = (Parcelable.Creator<?>) f.get(null);
}
catch (IllegalAccessException e) {
Log.e(TAG, "Illegal access when unmarshalling: " + name, e);
throw new BadParcelableException(
"IllegalAccessException when unmarshalling: " + name);
}
catch (ClassNotFoundException e) {
Log.e(TAG, "Class not found when unmarshalling: " + name, e);
throw new BadParcelableException(
"ClassNotFoundException when unmarshalling: " + name);
}
catch (NoSuchFieldException e) {
throw new BadParcelableException("Parcelable protocol requires a "
+ "Parcelable.Creator object called "
+ "CREATOR on class " + name);
}
if (creator == null) {
throw new BadParcelableException("Parcelable protocol requires a "
+ "non-null Parcelable.Creator object called "
+ "CREATOR on class " + name);
}
map.put(name, creator);
}
}
return creator;
}
实现Parcelable
步骤
- 必须要
implement Parcelable
。 - 重写
describeContents()
方法。 - 重写
writeToParcel(Parcel, int)
方法。 - 实例化静态内部对象
CREATOR
实现接口Parcelable.Creator
。
ParcelableValue
类继承Parcelable
,
public class ParcelableValue implements Parcelable {
private int i;
private double d;
private String s;
public ParcelableValue(int i, double d, String s) {
this.i = i;
this.d = d;
this.s = s;
}
public ParcelableValue(Parcel data) {
i = data.readInt();
d = data.readDouble();
s = data.readString();
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(i);
dest.writeDouble(d);
dest.writeString(s);
}
public static final Creator<ParcelableValue> CREATOR = new Parcelable.Creator<ParcelableValue>() {
@Override
public ParcelableValue createFromParcel(Parcel source) {
return new ParcelableValue(source);
}
@Override
public ParcelableValue[] newArray(int size) {
return new ParcelableValue[size];
}
};
}
3. 与Serializable序列化比较
- 在使用内存的时候,
Parcelable
比Serializable
性能高。 Parcelable
不能使用在要将数据存储在磁盘上的情况