Как читать / писать логическое значение при реализации интерфейса Parcelable?
Я пытаюсь сделать ArrayList
Parcelable
для того, чтобы передать в действие список пользовательских объектов. Я начинаю писать myObjectList
класс, который расширяется ArrayList<myObject>
и реализовать Parcelable
.
атрибуты MyObject
are boolean
но Parcel
нет метод read/writeBoolean
.
каков наилучший способ справиться с этим?
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.
Я обычно имею их в массиве и вызываю
writeBooleanArray
иreadBooleanArray
Если вам нужно упаковать одно логическое значение, вы можете сделать это:
parcel.writeBooleanArray(new boolean[] {myBool});
Я предложил вам самый простой способ реализовать Parcelable, если вы используете Android Studio.
просто подойдите к Файл - > Настройки - > Плагины - >Обзор Репозитория и поиск parcelable .См. изображение
Он будет автоматически создавать Parcelable.
и есть webiste также для этого. http://www.parcelabler.com/
AndroidStudio (с использованием 2.3 atm), после реализации Parcelable на вашем классе, вы можете просто держать указатель мыши над вашим имя класса и он просит вас добавить parcelable реализацию:
из четырех полей, он генерирует следующее:
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; ... }