417

我正在尝试制作一个ArrayList Parcelable以便将自定义对象列表传递给活动。我开始编写一个myObjectList扩展ArrayList<myObject>和实现的类Parcelable

的一些属性MyObjectbooleanParcel没有任何方法read/writeBoolean

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

4

13 回答 13

960

这就是我的做法......

写入包裹:

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

从包裹中读取:

myBoolean = in.readByte() != 0;     //myBoolean == true if byte != 0
于 2011-08-17T08:15:49.750 回答
70

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

dst.writeValue( myBool );

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

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

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

writeInt( (Boolean) v ? 1 : 0 );
于 2012-12-16T12:49:10.487 回答
19

你这样声明

 private boolean isSelectionRight;

 out.writeInt(isSelectionRight ? 1 : 0);

isSelectionRight  = in.readInt() != 0;

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

于 2013-07-16T06:01:41.417 回答
16

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

...
于 2017-03-30T07:01:58.493 回答
8

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

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

parcel.writeBooleanArray(new boolean[] {myBool});
于 2011-06-01T12:52:51.943 回答
8
out.writeInt(mBool ? 1 : 0); //Write
this.mBool =in.readInt()==1; //Read
于 2014-06-10T08:51:17.633 回答
6

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
于 2017-11-13T10:20:17.680 回答
5

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

只需转到File->Settings->Plugins->Browse Repository并搜索 parcelable 。参见图片

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

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

于 2016-06-09T15:42:43.843 回答
3

您可以使用屏蔽和移位将布尔值打包成一个字节。这将是最有效的方法,并且可能是他们希望你做的。

于 2011-06-01T12:48:37.793 回答
3

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

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

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

String.valueOf(theBoolean);

如果你要一个字节,你必须自己实现一个转换逻辑。

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

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

于 2011-06-01T12:51:10.377 回答
1

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

如果您更喜欢封装或隐藏大部分低级 Parceling 代码,您可以考虑使用我前段时间编写的一些代码来简化 Parcelable 的处理。

写入包裹非常简单:

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);
于 2015-02-21T11:15:31.503 回答
1

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

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

private PackageInfo(Parcel source) {
    ...
    requiredForAllUsers = source.readInt() != 0;
    ...
}
于 2017-12-21T13:28:04.203 回答
0

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

写入包裹:

dest.writeBoolean(booleanFlag);

从包裹中读取:

booleanFlag = in.readBoolean()

或者我们可以使用

写入包裹:

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

从包裹中读取:

booleanFlag = in.readByte() != 0;

于 2021-04-06T07:53:11.540 回答