Как читать / писать логическое значение при реализации интерфейса Parcelable?


Я пытаюсь сделать ArrayListParcelable для того, чтобы передать в действие список пользовательских объектов. Я начинаю писать myObjectList класс, который расширяется ArrayList<myObject> и реализовать Parcelable.

атрибуты MyObject are boolean но Parcel нет метод read/writeBoolean.

каков наилучший способ справиться с этим?

12 363

12 ответов:

вот как бы я это сделал...

writeToParcel:

dest.writeByte((byte) (myBoolean ? 1 : 0));     //if myBoolean == true, byte == 1

readFromParcel:

myBoolean = in.readByte() != 0;     //myBoolean == true if byte != 0

вы также можете использовать writeValue метод. На мой взгляд это самое простое решение.

dst.writeValue( myBool );

после этого вы можете легко получить его с помощью простого приведения к Boolean:

boolean myBool = (Boolean) source.readValue( null );

под капотом Android Framework будет обрабатывать его как целое число:

writeInt( (Boolean) v ? 1 : 0 );

вы заявляете вот так

 private boolean isSelectionRight;

написать

 out.writeInt(isSelectionRight ? 1 : 0);

читать

isSelectionRight  = (in.readInt() == 0) ? false : true;

логический тип должен быть преобразован в то, что поддерживает Parcel, и поэтому мы можем преобразовать его в int.

out.writeInt(mBool ? 1 : 0); //Write
this.mBool =in.readInt()==1; //Read

Я обычно имею их в массиве и вызываю writeBooleanArray и readBooleanArray

Если вам нужно упаковать одно логическое значение, вы можете сделать это:

parcel.writeBooleanArray(new boolean[] {myBool});

Я предложил вам самый простой способ реализовать Parcelable, если вы используете Android Studio.

просто подойдите к Файл - > Настройки - > Плагины - >Обзор Репозитория и поиск parcelable .См. изображение

enter image description here Он будет автоматически создавать Parcelable.

и есть webiste также для этого. http://www.parcelabler.com/

AndroidStudio (с использованием 2.3 atm), после реализации Parcelable на вашем классе, вы можете просто держать указатель мыши над вашим имя класса и он просит вас добавить parcelable реализацию:

enter image description here

из четырех полей, он генерирует следующее:

public class YourClass implements Parcelable{

String someString;
int someInt;
boolean someBoolean;
List<String> someList;

protected YourClass(Parcel in) {
    someString = in.readString();
    someInt = in.readInt();
    someBoolean = in.readByte() != 0;
    someList = in.createStringArrayList();
}

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(someString);
    dest.writeInt(someInt);
    dest.writeByte((byte) (someBoolean ? 1 : 0));
    dest.writeStringList(someList);
}

...

вы можете упаковать свои логические значения в байт, используя маскировку и сдвиг. Это был бы самый эффективный способ сделать это и, вероятно, то, что они ожидали бы от вас.

трудно определить реальный вопрос здесь. Я думаю, что это как иметь дело с булевыми при реализации Parcelable интерфейс.

некоторые атрибуты MyObject являются логическими, но Parcel не имеют никакого метода read / writeBoolean.

вам придется либо сохранить значение в виде строки, либо в виде байта. Если вы идете на строку, то вам придется использовать статический метод String класс valueOf() для разбора логического значения. Это не так эффективен как сохранение его в байт жесткой.

String.valueOf(theBoolean);

если вы идете на байт, вам придется реализовать логику преобразования самостоятельно.

byte convBool = -1;
if (theBoolean) {
    convBool = 1;
} else {
    convBool = 0;
}

при отключенииParcel объект вы должны позаботиться о преобразовании в исходный тип.

короткая и простая реализация в Котлин, С поддержкой nullable:

добавить методы в посылку

fun Parcel.writeBoolean(flag: Boolean?) {
    when(flag) {
        true -> writeInt(1)
        false -> writeInt(0)
        else -> writeInt(-1)
    }
}

fun Parcel.readBoolean(): Boolean? {
    return when(readInt()) {
        1 -> true
        0 -> false
        else -> null
    }
}

и использовать его:

parcel.writeBoolean(isUserActive)

parcel.readBoolean()        // For true, false, null
parcel.readBoolean()!!      // For only true and false

этот вопрос уже прекрасно ответили другие люди, если вы хотите сделать это на свой собственный.

Если вы предпочитаете инкапсулировать или скрыть большую часть кода низкоуровневого парцеллирования, вы можете рассмотреть возможность использования некоторые из кода, который я написал некоторое время назад для упрощения обработки parcelables.

писать в посылку так же просто, как:

parcelValues(dest, name, maxSpeed, weight, wheels, color, isDriving);

где цвет-это перечисление, а isDriving-логическое значение, например.

чтение с посылкой тоже не намного сложнее:

color = (CarColor)unparcelValue(CarColor.class.getClassLoader());
isDriving = (Boolean)unparcelValue();

просто взгляните на" ParceldroidExample " я добавил в проект.

наконец, он также сохраняет инициализатор создателя коротким:

public static final Parcelable.Creator<Car> CREATOR =
    Parceldroid.getCreatorForClass(Car.class);

есть много примеров в источниках Android (AOSP). Например, PackageInfo класс имеет логический член requiredForAllUsers и он сериализуется следующим образом:

public void writeToParcel(Parcel dest, int parcelableFlags) {
    ...
    dest.writeInt(requiredForAllUsers ? 1 : 0);
    ...
}

private PackageInfo(Parcel source) {
    ...
    requiredForAllUsers = source.readInt() != 0;
    ...
}