Serializable序列化

2018-07-03  本文已影响6人  gczxbb

实现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内存中,速度快。


任重而道远

上一篇下一篇

猜你喜欢

热点阅读