Flow Flow - 4 months ago 79
Android Question

How to marshall and unmarshall a Parcelable to a byte array with help of Parcel?

I want to marshall and unmarshall a Class that implements

Parcelable
to/from a byte array. I am well aware of the fact that the Parcelable representation is not stable and therefore not meant for long term storage of instances. But I have a use case where I need to serialize a object and it's not a showstopper if the unmarshalling fails because of an internal Android change. Also the class is already implementing the
Parcelable
interface.

Given an class
MyClass implements Parcelable
, how can I (ab)use the
Parcelable
interface for marshalling/unmarshalling?

Answer

First create a helper class ParcelableUtil.java:

public class ParcelableUtil {    
    public static byte[] marshall(Parcelable parceable) {
        Parcel parcel = Parcel.obtain();
        parceable.writeToParcel(parcel, 0);
        byte[] bytes = parcel.marshall();
        parcel.recycle();
        return bytes;
    }

    public static Parcel unmarshall(byte[] bytes) {
        Parcel parcel = Parcel.obtain();
        parcel.unmarshall(bytes, 0, bytes.length);
        parcel.setDataPosition(0); // this is extremely important!
        return parcel;
    }

    public static <T> T unmarshall(byte[] bytes, Parcelable.Creator<T> creator) {
        Parcel parcel = unmarshall(bytes);
        T result = creator.createFromParcel(parcel);
        parcel.recycle();
        return result;
    }
}

With the help of the util class above, you can marshall/unmarshall instances of your class MyClass implements Parcelable like so:

Unmarshalling (with CREATOR)

byte[] bytes = …
MyClass myclass = ParcelableUtil.unmarshall(bytes, MyClass.CREATOR);

Unmarshalling (without CREATOR)

byte[] bytes = …
Parcel parcel = ParcelableUtil.unmarshall(bytes);
MyClass myclass = new MyClass(parcel); // or MyClass.CREATOR.createFromParcel(parcel)

Marshalling

MyClass myclass = …
byte[] bytes = ParcelableUtil.marshall(myclass);