实现Serializable接口的实例对象,也可以写入Parcel,在进程之间传递,写入的内容是实例对象字节数组序列。
Parcel#writeValue方法。
public final void writeValue(Object v) {
if (v == null) {
writeInt(VAL_NULL);
} else if(...){
...
}
...
else {
...
if (v instanceof Serializable) {
// Must be last
writeInt(VAL_SERIALIZABLE);
writeSerializable((Serializable) v);
} else {
}
}
}
在Parcel#writeValue方法中,若数据类型是Serializable,先写入int类型的VAL_SERIALIZABLE,再写入Serializable对象。
Parcel#writeSerializable方法。
public final void writeSerializable(Serializable s) {
if (s == null) {
writeString(null);
return;
}
String name = s.getClass().getName();
writeString(name);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(s);
oos.close();
writeByteArray(baos.toByteArray());
} catch (IOException ioe) {
}
}
创建一个字节数组输出流ByteArrayOutputStream,向ObjectOutputStream中写入Serializable对象,转换成字节序列写入Parcel。Parcel#writeByteArray方法向Parcel写入字节数组。
Parcel#readValue方法
public final Object readValue(ClassLoader loader) {
int type = readInt();
switch (type) {
...
case VAL_SERIALIZABLE:
return readSerializable(loader);
...
}
}
若是Serializable类型对象。
private final Serializable readSerializable(final ClassLoader loader){
String name = readString();
if (name == null) {
return null;
}
byte[] serializedData = createByteArray();
ByteArrayInputStream bais = new ByteArrayInputStream(serializedData);
try {
ObjectInputStream ois = new ObjectInputStream(bais) {
@Override
protected Class<?> resolveClass(ObjectStreamClass osClass)
throws IOException, ClassNotFoundException {
if (loader != null) {
Class<?> c = Class.forName(osClass.getName(), false, loader);
if (c != null) {
return c;
}
}
return super.resolveClass(osClass);
}
};
return (Serializable) ois.readObject();
} catch (IOException ioe) {
} catch (ClassNotFoundException cnfe) {
}
}
创建一个字节数组输入流ByteArrayInputStream,从ObjectInputStream输入流中读取字节序列,再把它们反序列化为实例对象。
Serializable序列化传递用到输出流和输入流,使用IO读写存储在硬盘上,速度慢,序列化过程中会产生临时对象,引起GC频繁。Parcelable传递直接在内存中读取,数据在Native内存中,速度快。
任重而道远
网友评论