Seriaizeable 可以序列化长期保存到本地文件里,那么Parcelable 可不可以呢?

在阅读了Parcel的源码之后,发现了很多的 writexxxreadxxx 方法,这个后续再做分析,这篇主要描述一下另外两个方法marshallunmarshall, 这两个函数是相互对应的.

marshall: Parcel 将自身所保存的所有数据以 byte 数组的形式返回

/**
 * Returns the raw bytes of the parcel.
 *
 * <p class="note">The data you retrieve here <strong>must not</strong>
 * be placed in any kind of persistent storage (on local disk, across
 * a network, etc).  For that, you should use standard serialization
 * or another kind of general serialization mechanism.  The Parcel
 * marshalled representation is highly optimized for local IPC, and as
 * such does not attempt to maintain compatibility with data created
 * in different versions of the platform.
 */
public final byte[] marshall() {
    return nativeMarshall(mNativePtr);
}

unmarshall: 从 byte 数组里获取数据,存入自身 Parcel

/**
 * Set the bytes in data to be the raw bytes of this Parcel.
 */
public final void unmarshall(byte[] data, int offset, int length) {
    nativeUnmarshall(mNativePtr, data, offset, length);
}

既然Parcel 可以转化成 byte[],也可以从byte[] 里获取数据,那么我们就可以这样做:


package com.example.dongyayun.androidartsearch.Parcelable;

import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;

/**
 * Created by dongyayun on 16/1/17.
 */
public class ParcelableUtil {
    public static byte[] marshall(Parcelable parceable) {
        Parcel parcel = Parcel.obtain();
        parcel.setDataPosition(0);
        parceable.writeToParcel(parcel, 0);
        byte[] bytes = parcel.marshall();

        Log.d("ParcelableTest", "bytes = " + String.valueOf(bytes) + "parcel" + parcel.toString());
        parcel.recycle();
        return bytes;
    }

    public static Parcel unmarshall(byte[] bytes) {
        Parcel parcel = Parcel.obtain();
        parcel.unmarshall(bytes, 0, bytes.length);
        parcel.setDataPosition(0);
        return parcel;
    }

}

// MainActivity.java
private void testParcelableMarshall() {
    ParcelableTest parcelableTest = new ParcelableTest(1, 2, 3, "HelloWorld!");
    parcelableTest.toString();

    byte[] bytes = ParcelableUtil.marshall(parcelableTest);

    SharedPreferences.Editor parcelableEditor = getSharedPreferences("parcelable", 0).edit();
    //parcelableEditor.putString("parcelable", new String(bytes));
    parcelableEditor.putString("parcelable", Base64.encodeToString(bytes, 0));
    parcelableEditor.commit();


    SharedPreferences parcelable = getSharedPreferences("parcelable", 0);
    //Parcel parcel = ParcelableUtil.unmarshall(parcelable.getString("parcelable", "default").getBytes());
    Parcel parcel = ParcelableUtil.unmarshall(Base64.decode(parcelable.getString("parcelable", "default"), 0));

    Log.d("ParcelableTest", String.valueOf(bytes).toString() + "bytes = " + parcelable.getString("parcelable", "default").toString() + "parcel" + parcel.toString());
    ParcelableTest parcelableTest1 = null;
    parcelableTest1 = ParcelableTest.CREATOR.createFromParcel(parcel);
    parcelableTest1.toString();
}

在调用 testParcelableMarshall() 之后结果如下:

D/ParcelableTest( 7923): t1 = 1 t2 = 2 t3 = 3 a = HelloWorld!
D/ParcelableTest( 7923): Call writeToParcel
D/ParcelableTest( 7923): bytes = [B@3043c569parcelandroid.os.Parcel@b373bee
D/ParcelableTest( 7923): [B@3043c569bytes = AQAAAAIAAAADAAAACwAAAEgAZQBsAGwAbwBXAG8AcgBsAGQAIQAAAA==
D/ParcelableTest( 7923): parcelandroid.os.Parcel@b373bee
D/ParcelableTest( 7923): Call createFromParcel
D/ParcelableTest( 7923): Call ParcelableTest
D/ParcelableTest( 7923): t1 = 1 t2 = 2 t3 = 3 a = HelloWorld!

事实证明,Parcelable 成功的保存到了持久化的文件里。

如图所示: 如图所示