实现 Parcelable 接口时如何读/写布尔值?

发布于 2024-11-11 15:24:23 字数 300 浏览 3 评论 0原文

我正在尝试创建一个 ArrayList ,以便将自定义对象列表传递给活动。我开始编写一个 myObjectList 类,它扩展 ArrayList 并实现 Parcelable

MyObject 的某些属性是 boolean,但 Parcel 没有任何方法 read/writeBoolean

处理这个问题的最佳方法是什么?

I'm trying to make an ArrayList Parcelable in order to pass to an activity a list of custom object. I start writing a myObjectList class which extends ArrayList<myObject> and implement Parcelable.

Some attributes of MyObject are boolean but Parcel don't have any method read/writeBoolean.

What is the best way to handle this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(14

如果没有你 2024-11-18 15:24:24

您可以使用掩码和移位将布尔值打包到一个字节中。这将是最有效的方法,也可能是他们希望你做的。

You could pack your boolean values into a byte using masking and shifting. That would be the most efficient way to do it and is probably what they would expect you to do.

贩梦商人 2024-11-18 15:24:24

这里很难确定真正的问题。我想这就是实现 Parcelable 接口时如何处理布尔值。

MyObject 的某些属性是布尔值,但 Parcel 没有任何 read/writeBoolean 方法。

您必须将该值存储为字符串或字节。如果您选择字符串,则必须使用 String 类的静态方法 valueOf() 来解析布尔值。它不如将其保存在一个字节中那么有效。

String.valueOf(theBoolean);

如果您选择一个字节,则必须自己实现转换逻辑。

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

解组 Parcel 对象时,您必须注意到原始类型的转换。

It is hard to identify the real question here. I guess it is how to deal with booleans when implementing the Parcelable interface.

Some attributes of MyObject are boolean but Parcel don't have any method read/writeBoolean.

You will have to either store the value as a string or as a byte. If you go for a string then you'll have to use the static method of the String class called valueOf() to parse the boolean value. It isn't as effective as saving it in a byte tough.

String.valueOf(theBoolean);

If you go for a byte you'll have to implement a conversion logic yourself.

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

When unmarshalling the Parcel object you have to take care of the conversion to the original type.

挽你眉间 2024-11-18 15:24:24

这个问题已经被其他人完美回答了,如果你想自己做的话。

如果您希望封装或隐藏大部分低级打包代码,您可以考虑使用 我之前编写的一些代码用于简化对 Parcelable 的处理。

写入 Parcel 非常简单:

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

例如,其中 color 是一个枚举,isDriving 是一个布尔值。

从包裹中读取数据也并不困难:

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

只需查看我添加到项目中的“ParceldroidExample”即可。

最后,它还使 CREATOR 初始值设定项保持简短:

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

This question has already been answered perfectly by other people, if you want to do it on your own.

If you prefer to encapsulate or hide away most of the low-level parceling code, you might consider using some of the code I wrote some time ago for simplifying handling of parcelables.

Writing to a parcel is as easy as:

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

where color is an enum and isDriving is a boolean, for example.

Reading from a parcel is also not much harder:

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

Just take a look at the "ParceldroidExample" I added to the project.

Finally, it also keeps the CREATOR initializer short:

public static final Parcelable.Creator<Car> CREATOR =
    Parceldroid.getCreatorForClass(Car.class);
素年丶 2024-11-18 15:24:24

Android (AOSP) 源代码中有很多示例。例如,PackageInfo类有一个布尔成员requiredForAllUsers,它的序列化如下:

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

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

There are many examples in the Android (AOSP) sources. For example, PackageInfo class has a boolean member requiredForAllUsers and it is serialized as follows:

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

private PackageInfo(Parcel source) {
    ...
    requiredForAllUsers = source.readInt() != 0;
    ...
}
庆幸我还是我 2024-11-18 15:24:24

对于 API 29 及更高版本,我们可以使用

writeToParcel:

dest.writeBoolean(booleanFlag);

readFromParcel:

booleanFlag = in.readBoolean()

或者我们可以使用

writeToParcel:

dest.writeByte((byte) (booleanFlag ? 1 : 0));

readFromParcel:

booleanFlag = in.readByte() != 0;

For API 29 and above we can use

writeToParcel:

dest.writeBoolean(booleanFlag);

readFromParcel:

booleanFlag = in.readBoolean()

Or We can use

writeToParcel:

dest.writeByte((byte) (booleanFlag ? 1 : 0));

readFromParcel:

booleanFlag = in.readByte() != 0;

简美 2024-11-18 15:24:24

从 api 29 开始,您现在可以在 Parcel 类中使用 readBoolean()
请参阅 https://developer.android.com/reference/android/os /Parcel#readBoolean() 了解更多

Since api 29, you can now use the readBoolean() in the Parcel class.
see https://developer.android.com/reference/android/os/Parcel#readBoolean() for more

薄情伤 2024-11-18 15:24:23

这是我的做法...

writeToParcel:

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

readFromParcel:

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

Here's how I'd do it...

writeToParcel:

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

readFromParcel:

myBoolean = in.readByte() != 0;     //myBoolean == true if byte != 0
倾听心声的旋律 2024-11-18 15:24:23

您还可以使用 writeValue< /a> 方法。在我看来,这是最直接的解决方案。

dst.writeValue( myBool );

之后,您可以通过简单地转换为 Boolean 轻松检索它:

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

在幕后,Android 框架会将其作为整数处理:

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

You could also make use of the writeValue method. In my opinion that's the most straightforward solution.

dst.writeValue( myBool );

Afterwards you can easily retrieve it with a simple cast to Boolean:

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

Under the hood the Android Framework will handle it as an integer:

writeInt( (Boolean) v ? 1 : 0 );
旧街凉风 2024-11-18 15:24:23

您像这样声明

 private boolean isSelectionRight;

write

 out.writeInt(isSelectionRight ? 1 : 0);

read

isSelectionRight  = in.readInt() != 0;

boolean 类型需要转换为 Parcel 支持的类型,因此我们可以将其转换为 int。

you declare like this

 private boolean isSelectionRight;

write

 out.writeInt(isSelectionRight ? 1 : 0);

read

isSelectionRight  = in.readInt() != 0;

boolean type needs to be converted to something that Parcel supports and so we can convert it to int.

不打扰别人 2024-11-18 15:24:23

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);
}

...

AndroidStudio (using 2.3 atm), after implementing Parcelable on your class, you can simply hold your mouse pointer over your class name and it asks you to add the parcelable implementation:

enter image description here

From the four fields, it generates the following:

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);
}

...
﹎☆浅夏丿初晴 2024-11-18 15:24:23

我通常将它们放在一个数组中并调用 writeBooleanArray 和 readBooleanArray

如果您需要打包单个布尔值,您可以这样做:

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

I normally have them in an array and call writeBooleanArray and readBooleanArray

If it's a single boolean you need to pack, you could do this:

parcel.writeBooleanArray(new boolean[] {myBool});
ら栖息 2024-11-18 15:24:23
out.writeInt(mBool ? 1 : 0); //Write
this.mBool =in.readInt()==1; //Read
out.writeInt(mBool ? 1 : 0); //Write
this.mBool =in.readInt()==1; //Read
¢好甜 2024-11-18 15:24:23

Kotlin 中实现简短且可空的支持:

向 Parcel 添加方法

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

Short and simple implementation in Kotlin, with nullable support:

Add methods to Parcel

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
    }
}

And use it:

parcel.writeBoolean(isUserActive)

parcel.readBoolean()        // For true, false, null
parcel.readBoolean()!!      // For only true and false
不打扰别人 2024-11-18 15:24:23

如果您使用 Android Studio,我建议您采用最简单的方法来实现 Parcelable。

只需转到文件->设置->插件->浏览存储库并搜索parcelable。参见图片

在此处输入图像描述
它会自动创建 Parcelable。

还有一个网站也可以这样做。 http://www.parcelabler.com/

I suggested you the easiest way to implement Parcelable if you are using Android Studio.

Simply go to File->Settings->Plugins->Browse Repository and search for parcelable .See image

enter image description here
It will automatically create Parcelable.

And there is a webiste also for doing this. http://www.parcelabler.com/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文