安卓 Kotlin 中的 Parcelable

10

我有这样的Java可包含对象:

@SuppressWarnings("rawtypes")
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
    public KwerendaGraficzna createFromParcel(Parcel in) {
        return new KwerendaGraficzna(in);
    }

    public KwerendaGraficzna[] newArray(int size) {
        return new KwerendaGraficzna[size];
    }
};

现在尝试使用Kotlin实现:

companion object {
    @SuppressWarnings("rawtypes")
    val CREATOR: Parcelable.Creator<KwerendaGraficzna!> = object : Parcelable.Creator<KwerendaGraficzna!> {
        override fun createFromParcel(`in`: Parcel): KwerendaGraficzna {
            return KwerendaGraficzna(`in`)
        }

        override fun newArray(size: Int): Array<KwerendaGraficzna!> {
            return arrayOfNulls<KwerendaGraficzna!>(size)
        }
    }
}

arrayOfNulls编译失败,需要KwerendaGraficzna,但实际上它声称接收到了KwerendaGraficzna?。那么我该怎么做呢?


另请参见https://dev59.com/6VwX5IYBdhLWcg3wpw1h。 - albert c braun
2个回答

17

我怀疑您正在使用过时的 Kotlin 编译器(因为您使用了 !)。这是一个使用最新版本正确编译的版本:

companion object {
    @JvmField
    val CREATOR = object : Parcelable.Creator<KwerendaGraficzna> {
        override fun createFromParcel(`in`: Parcel): KwerendaGraficzna {
            return KwerendaGraficzna(`in`)
        }

        override fun newArray(size: Int): Array<KwerendaGraficzna?> {
            return arrayOfNulls(size)
        }
    }
}

由于Parcelable.Creator需要一个公共静态字段,因此我们需要使用@JvmFieldJvmStatic标记CREATOR属性。


谢谢,我稍后会检查它。不过有一个问题 - 为什么 Kotlin 需要类型规范而 Java 不需要呢? - ssuukk
@ssuukk 不太清楚你的意思。Kotlin使用声明点变异,而不是使用点变异。 - miensol
@miensol,你认为这个还能用吗?我最终遇到了一个异常:当尝试从 bundle 中读取时,Parcelable 协议要求一个名为 CREATOR 的 Parcelable.Creator 对象。 - Eggman87
1
@miensol 谢谢!最终在这里提出了一个问题并得到了答案。值得注意的是,只有对于CREATOR,您才需要JvmField注释。 - Eggman87
@Eggman87 刚刚看了生成的类,你是对的。不过似乎很奇怪,即使我们没有指示编译器这样做,它也会生成一个静态字段。 - miensol

0
你不需要实现所有的样板代码。
相反,
@Parcelize
data class KwerendaGraficzna(val a: Int, val b: String): Parcelable{
    // TODO: others code
}

就是这样。

您需要在build.gradle中将experimental设置为true,才能应用上述方法。

android{
    compileSdkVersion 30
    
    defaultConfig{
        applicationId "com.example"
        minSdkVersion 25
        targetSdkVersion 30
        ...
    }

    ...

    androidExtensions {
        experimental = true
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接