如何在 Parcel 的帮助下将 Parcelable 编组和解组为字节数组?

Posted

技术标签:

【中文标题】如何在 Parcel 的帮助下将 Parcelable 编组和解组为字节数组?【英文标题】:How to marshall and unmarshall a Parcelable to a byte array with help of Parcel? 【发布时间】:2013-08-02 17:34:42 【问题描述】:

我想编组和解组一个实现Parcelable 到/从字节数组的类。 我很清楚 Parcelable 表示不稳定,因此不适合长期存储实例。但我有一个用例,我需要序列化一个对象,它不是一个展示停止器如果由于内部 android 更改而导致解组失败。此外,该类已经实现了Parcelable 接口。

给定一个类MyClass implements Parcelable,我如何(ab)使用Parcelable 接口进行编组/解组?

【问题讨论】:

【参考方案1】:

首先创建一个帮助类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;
    

借助上面的 util 类,您可以像这样编组/取消编组您的类 MyClass implements Parcelable 的实例:

解组(使用CREATOR

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

解组(不带CREATOR

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

编组

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

【讨论】:

parcel.setDataPosition(0); // this is extremely important! 这对我很有帮助。 Android 文档的缺失,真是糟透了。 非常感谢您的提示。实现 Parcelable(这很容易出错,如果做得不好,你会得到无意义的运行时异常和愤怒的客户)就是这样一个 PITA——我在我的代码中完全避免使用 Parcelables,我正在使用 Serializables。在现代手机上,速度几乎不明显。 然而,这种方法的唯一问题是解组实现 Parcelable 的类的子类不会那么简单。您需要传递额外的信息,您可以从中判断要使用的创建者的正确性。 流程,如何将您的 util 类用于 ParcelableArrayList 案例?非常感谢! @Flow 在 Parcelable 实现类中在哪里做 Marshalling 和 UnMarshalling【参考方案2】:
public static byte[] pack(Parcelable parcelable) 
    Parcel parcel = Parcel.obtain();
    parcelable.writeToParcel(parcel, 0);
    byte[] bytes = parcel.marshall();
    parcel.recycle();
    return bytes;


public static <T> T unpack(byte[] bytes, Parcelable.Creator<T> creator) 
    Parcel parcel = Parcel.obtain();
    parcel.unmarshall(bytes, 0, bytes.length);
    parcel.setDataPosition(0);
    return creator.createFromParcel(parcel);


MyObject myObject = unpack(new byte[]/* bytes */, MyObject.CREATOR);

【讨论】:

请对你贴的代码做一个简单的说明,以便OP理解。

以上是关于如何在 Parcel 的帮助下将 Parcelable 编组和解组为字节数组?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 PrettyFaces 的帮助下将长的 Liferay URL 映射到友好的 URL?

如何在不创建架构的情况下将 CSV 文件加载到 BigQuery

如何在 Parcel 中使用 jQuery UI

如何利用Cloudera Manager来手动安装parcel包

如何使用 Parcel 2 在 React 中使用 SVG 内联?

如何在 CRA 项目中用 parcel 替换 webpack?