如何为 Parcelable 接口存储布尔值 属性?

How to store boolean property for Parcelable interface?

我有一个 data 对象,UserUser 的属性之一是 Boolean。我不知道如何存储这个 Boolean,因为没有开箱即用的 writeBoolean()

根据我在网上搜索到的内容,存储 Boolean 属性 的一种方法是使用 writeInt() 方法和三元运算符。

所以我在这里试了一下:

data class User(val contactNumber: String,
                val email: String,
                val fullName: String,
                val isAdmin: Boolean,
                val organization: String,
                val unitNumber: String) : Parcelable {

override fun writeToParcel(dest: Parcel?, flags: Int) {
        dest?.writeString(contactNumber)
        dest?.writeString(email)
        dest?.writeString(fullName)
        dest?.writeInt(isAdmin ? 1 : 0)
        dest?.writeString(organization)
        dest?.writeString(unitNumber)
    }

}

但是这种语法似乎只适用于 Java 而不是 Kotlin。我收到指示 Unexpected tokens (use ':' to separate expressions on the same line 的编译器错误。我如何在 Kotlin 中完成此操作?

kotlin 不支持三元运算符 使用 if-else 代替

writeInt(if(isAdmin) 1 else 0)

我正在使用 writeValue,它对可空变量也很有用

dest.writeValue(this.booleanVar)
booleanVar = parcel.readValue(Boolean::class.java.classLoader) as? Boolean? 

如果它可以为 null,如果不能则添加 ?: false

upd:正如其他答案所指出的 dest 变量不能为空。据我所知,它在使用 Android Studio 进行代码转换后标记为可为空。如果您更好地使用该功能,请仔细检查您的代码,因为有时转换可能无法正常工作。

一般来说 ?.。您可以使用 let operator

重写它
dest?.let { it ->
  it.write(....)

甚至更好

dest ?: retrun
  1. Java 的 isAdmin ? 1 : 0 在 Kotlin 中的语法是 if (isAdmin) 1 else 0

  2. dest 不能合理地成为 null,所以你可以将其类型更改为 Parcel 并将所有 ?. 更改为 ..

但真正的答案是:使用 @Parcelize 并让编译器生成所有代码,因此您 不能 在添加新属性时忘记更改它, 或者弄错顺序, 或者...

1.) 使用这个方便的扩展功能:

fun Parcel.readBoolean(): Boolean = readByte() > 0

fun Parcel.writeBoolean(bool: Boolean) {
    writeByte((if (bool) 1 else 0).toByte())
}

2.) 在

override fun writeToParcel(dest: Parcel?, flags: Int) {

dest: Parcel! 是一个 平台类型 ,所以如果你知道它 永远不会 为 null,则将其指定为可空类型的理由为零。

改用override fun writeToParcel(dest: Parcel, flags: Int) {