美文网首页
Serializable序列化

Serializable序列化

作者: gczxbb | 来源:发表于2018-07-03 20:33 被阅读6次

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


    任重而道远

    相关文章

      网友评论

          本文标题:Serializable序列化

          本文链接:https://www.haomeiwen.com/subject/kpujuftx.html