背景:

Android在序列化中,官方给出了Parcelable的方案,关于Parcelable的使用,可以参考Parcelable序列化教程

有了序列化的详细使用,我们肯定想知道如何把Parcelable序列化保存起来呢?常见的保存就是网络存储或者本地存储。

知道了本地存储,网络就是将byte字节传给服务器。接下来我们将会介绍设备本机上的序列化和反序列化

1.序列化

public static void save(Context context, Parcelable parcelable, String fileName) {


    File file = new File(context.getExternalCacheDir().getAbsolutePath() + File.separator + fileName);

    try {
        if (!file.exists()) {
            file.createNewFile();
        }
        FileOutputStream out = (new FileOutputStream(file));
        BufferedOutputStream bos = new BufferedOutputStream(out);
        Parcel parcel = Parcel.obtain();
        parcel.writeParcelable(parcelable, 0);
        bos.write(parcel.marshall());
        bos.flush();
        bos.close();
        out.flush();
        out.close();

    } catch (Exception e) {
        e.printStackTrace();

    }


}


在序列化过程中,保存的位置和文件的读写。如果是安全比较高的,建议保存在cache文件夹下,这样避免被清除了。文件名最好用英文,上面的方法就是采用cache文件夹。

文件的读写不在过多介绍

如何将Parcelable的对象变成二进制?离不开我们的老朋友Parcel,Parcel在Parcelable的序列化中也出现了,读写变量。

这里面同样,通过 Parcel parcel = Parcel.obtain();创建一个临时对象,


/**
 * Retrieve a new Parcel object from the pool.
 */
public static Parcel obtain() {
    final Parcel[] pool = sOwnedPool;
    synchronized (pool) {
        Parcel p;
        for (int i=0; i<POOL_SIZE; i++) {
            p = pool[i];
            if (p != null) {
                pool[i] = null;
                if (DEBUG_RECYCLE) {
                    p.mStack = new RuntimeException();
                }
                return p;
            }
        }
    }
    return new Parcel(0);
}


接下来我们将Parcelable的对象保存到parcel中

parcel.writeParcelable(parcelable, 0);

通过parcel.marshall()将对象变成byte字节。


public final byte[] marshall() { return nativeMarshall(mNativePtr); }


这样我们将byte[]写到我们创建的文件中,至此,序列化已保存到我们的本地设备中

2.反序列化

了解了序列化过程,反序列化也是这些东西参与进来。

public static Parcelable getBeanByFileName(Context context, String fileName) {
    File file = new File(context.getExternalCacheDir().getAbsolutePath() + File.separator + fileName);
    People person=null;
    try {
        FileInputStream in = new FileInputStream(file);
        byte[] bytes = new byte[in.available()];
        in.read(bytes);
        Parcel parcel = Parcel.obtain();
        parcel.unmarshall(bytes, 0, bytes.length);
        parcel.setDataPosition(0);
         person = parcel.readParcelable(Thread.currentThread().getContextClassLoader());


    } catch (Exception e) {
        e.printStackTrace();
    }
    return person;

}

2.1找到序列化的文件位置

2.2把文件的中信息读取存入字节数组。

2.3 创建一个临时的 Parcel parcel = Parcel.obtain();对象

2.4 通过parcel进行反序列化 parcel.unmarshall(bytes, 0, bytes.length);

2.5 将parcel反序列化对象读取出来

person = parcel.readParcelable(Thread.currentThread().getContextClassLoader());

这样反序列化结束。

关于parcel unmarshall和marshall,感兴趣的可以自行查看源码。

文件名:一定要组织好,否则存在失败问题。上述方法已测试,可以执行