如何在实现Parcelable接口时读写一个布尔值?

我试图做一个ArrayList Parcelable为了传递给一个活动的自定义对象列表。 我开始写一个扩展ArrayList并实现ParcelablemyObjectList类。

MyObject某些属性是booleanParcel没有任何方法read/writeBoolean

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

这是我该怎么做的…

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框架将把它作为一个整数来处理:

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

你这样宣布

  private boolean isSelectionRight; 

  out.writeInt(isSelectionRight ? 1 : 0); 

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

布尔types需要被转换为Parcel支持的东西,所以我们可以将其转换为int。

我通常有他们在一个数组,并调用writeBooleanArrayreadBooleanArray

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

 parcel.writeBooleanArray(new boolean[] {myBool}); 
 out.writeInt(mBool ? 1 : 0); //Write this.mBool =in.readInt()==1; //Read 

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

只需进入文件 – >设置 – >插件 – >浏览存储库,并搜索parcelable。见图像

在这里输入图像说明 它会自动创建Parcelable。

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

AndroidStudio(使用2.3 atm),在你的类上实现了Parcelable后,你可以简单地将你的鼠标指针放在你的类名上 ,并要求你添加parcelable实现:

在这里输入图像说明

从四个领域,它产生以下内容:

 public class YourClass implements Parcelable{ String someString; int someInt; boolean someBoolean; List 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。

您必须将该值存储为字符串或字节。 如果你想要一个字符串,那么你将不得不使用称为valueOf()String类的静态方法来解析布尔值。 它不像在一个字节难以保存它有效。

 String.valueOf(theBoolean); 

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

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

解编Parcel对象时,必须注意转换为原始types。

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

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

写一个包裹就像:

 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 CREATOR = Parceldroid.getCreatorForClass(Car.class); 

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 

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

 public void writeToParcel(Parcel dest, int parcelableFlags) { ... dest.writeInt(requiredForAllUsers ? 1 : 0); ... } private PackageInfo(Parcel source) { ... requiredForAllUsers = source.readInt() != 0; ... }