Как упорядочить и разобрать Parcelable в массив байтов с помощью Parcel?

Я хочу упорядочить и рассортировать класс, который реализует Parcelable в/из массива байтов. Мне хорошо известно, что представление Parcelable нестабильно и поэтому не предназначено для длительного хранения экземпляров. Но у меня есть случай использования, когда мне нужно сериализовать объект, и это не мешает если распаковка не удалась из-за внутреннего изменения Android. Также класс уже реализует интерфейс Parcelable.

Учитывая класс MyClass implements Parcelable, как я могу (ab) использовать интерфейс Parcelable для сортировки/демаршаллинга?


person Flow    schedule 01.08.2013    source источник


Ответы (2)


Сначала создайте вспомогательный класс 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);
person Flow    schedule 01.08.2013
comment
parcel.setDataPosition(0); // this is extremely important! это мне очень помогает. отсутствие Android-документа об этом действительно отстой. - person Jiang YD; 17.12.2015
comment
Большое спасибо за этот совет. Реализация Parcelable (которая чрезвычайно подвержена ошибкам, и вы получите бессмысленные исключения во время выполнения и разгневанных клиентов, если не сделаете это правильно) является такой PITA - я вообще избегаю Parcelables в своем коде и использую Serializables. На современных телефонах прирост скорости почти не заметен. - person Martin Vysny; 15.03.2016
comment
Единственная проблема с этим подходом, однако, заключается в том, что деупорядочение подкласса класса, реализующего Parcelable, будет не таким простым. Вам нужно будет передать дополнительную информацию, по которой вы сможете судить о правильном Создателе для использования. - person bosphere; 13.08.2016
comment
Flow, Как использовать ваш класс util для случая ParcelableArrayList? Большое тебе спасибо! - person anthony; 13.08.2016
comment
@Flow, где выполнять Marshalling и UnMarshalling в классе реализации Parcelable - person rupesh; 25.09.2017
comment
Работает нормально с пользовательскими объектами. Но есть ли способ отправить список данных, который является настраиваемым объектом, расширяющим Parcelable. Если возможно, какую модификацию я должен сделать? - person Chathuranga Shan Jayarathna; 25.11.2018

person    schedule
comment
Пожалуйста, дайте краткое объяснение кода, который вы разместили, чтобы ОП было легче его понять. - person Jatin; 17.03.2014