Android parcelable - 写入 nullable long

Android parcelable - write nullable long

我有我的包裹class文章:

class Article : Parcelable {

    var image: Long? = null
    var category: String? = null
    var videos: String? = null

    constructor(data: JSONObject) {
        if (condition) image = 50000L
        category = data.getString("category")
        videos = data.getString("videos")
    }

    private constructor(parcel: Parcel) {
        image = parcel.readLong()
        category = parcel.readString()
        videos = parcel.readString()
    }

    override fun writeToParcel(dest: Parcel, flags: Int) {
        dest.writeLong(image) // error here
        dest.writeString(category)
        dest.writeString(videos)
    }

    override fun describeContents(): Int = 0

    companion object {
        @JvmField val CREATOR: Parcelable.Creator<Article> = object : Parcelable.Creator<Article> {
            override fun createFromParcel(parcel: Parcel): Article = Article(parcel)
            override fun newArray(size: Int): Array<Article?> = arrayOfNulls(size)
        }
    }
}

但是我的 class 在写入图像变量时出现类型不匹配。它期待的是 Long 而不是 Long?。我知道如果我这样做可以解决这个问题:

dest.writeLong(image!!)

但问题是这个 var 在我的上下文中可能真的是 null。 我不想将我的图像 var 定义为默认值,如 0。我真的希望 var 保持可为空。

有什么方法可以编写可为空的变量吗?

我现在使用扩展函数来解决我项目中的这些问题:

private const val NULL_ELEMENT_FLAG = 0;
private const val NONNULL_ELEMENT_FLAG = 1;

Parcel.writeNullableLong(l: Long?) {
    if (l != null) {
        writeInt(NONNULL_ELEMENT_FLAG);
        writeLong(l);
    } else {
        writeInt(NULL_ELEMENT_FLAG);
    }
}

Parcel.readNullableLong(): Long? =
    when (readInt()) {
        NONNULL_ELEMENT_FLAG -> readLong()
        else -> null
    }

在 Java 中,我处理 Long(与 long 相对)的方式仿照 Android 源代码编写其他 "nullable"类型:您首先编写某种标记值来指示 null 与非 null,然后您有条件地写入实际值。

private static final int NULL_ELEMENT_FLAG = 0;
private static final int NONNULL_ELEMENT_FLAG = 1;

public static void writeLong(Parcel dest, Long l) {
    if (l != null) {
        dest.writeInt(NONNULL_ELEMENT_FLAG);
        dest.writeLong(l);
    }
    else {
        dest.writeInt(NULL_ELEMENT_FLAG);
    }
}

public static Long readLong(Parcel in) {
    if (in.readInt() != NULL_ELEMENT_FLAG) {
        return in.readLong();
    }
    else {
        return null;
    }
}

希望你能将其适应 kotlin。

在 Kotlin 中,您必须处理 Kotlin 原始类型 的空值情况,即 Java 中的 objectsLong 而不是 long)。您可以将以下逻辑应用于任何此类类型。

private fun writeNullableLongToParcel(l: Long?): Long = when(l) {
      null -> -1
      else -> l
}

对于Boolean,你做这样的事情:

private fun writeBooleanToParcel(bool: Boolean?): Int = when(bool) {
      true -> 1
      false -> 0
      else -> -1
}

将这些添加到您的 Parcelable 数据 class 并在 writeToParcel

中使用它们
parcel?.writeLong(writeNullableLongToParcel(myLong))

如果您的图像变量应保持可为空

parcel.readValue(Long::class.java.classLoader) as? Long

parcel.writeValue(image)

如果不为空则写入值,否则为默认值

longValue?.let { parcel.writeLong(it) }?:let{ parcel.writeLong(DEFAULT_VALUE)}