Kotlin的“@Parcelize”是否适用于非数据类?

时间:2018-01-25 06:34:41

标签: android kotlin

我有简单的数据类。我的意思是,它们在逻辑上是数据类,但不是data class,因为我需要继承和其他构造函数。它们只包含(基本类型Int?String?List<String>?等)和构造函数的字段。

我需要将它们(它们的所有字段都需要传递)从Activity传递给Activity,所以我需要让它们成为parcellisable(或者有更好的方法吗?)。我首先将其创建为data class,然后添加了@Parcelize。即使有一条警告和红线表示“CREATOR”或其他东西,我可以忽略它们,并且应用程序按预期工作。

但是,由于上述原因,我将它们更改为普通类,突然出现编译错误。

Error:java.util.NoSuchElementException: Collection contains no element matching the predicate.
    at org.jetbrains.kotlin.android.parcel.ParcelableCodegenExtension.getPropertiesToSerialize(ParcelableCodegenExtension.kt:374)
    ....too long...
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

Error:Execution failed for task ':app:kaptGenerateStubsDebugKotlin'. Internal compiler error. See log for more details

我该如何解决这个问题?我应该使用data class吗?但是我需要解析一个JSON对象来创建它们。这些类看起来像这些(不是实际的类,但为了说明目的而简化)。有没有比手工实施那些无聊,笨重的可分割代码更好的方法?

@Parcelize
open class Dog():Parcelable
{
    var someField1;
    var someField2;
    constructor(data:JSON):this()
    {
       //parse data to set the fields.
    }
}

@Parcelize
class Doge:Dog
{
    var someField3;
    var someField4;

    constructor():super(); //I do not use it, but for parcellable
    constructor(data:JSON):super(data)
    {
       //parse data to set the fields.
    }
}

PS。我不得不切换到PaperParcel。它与Kotlin非常相似,但它不需要主要的构造函数。它只需要与任何构造函数相同的东西,所以我可以创建一个具有与字段相同的参数名称的辅助构造函数,并且它可以工作。虽然,我想知道为什么CREATOR无法自动创建。

例如,

@PaperParcel
class Doge:Dog
{
    var someField3;
    var someField4;

    //Needed only for PaperParcel
    constructor(someField3, someField4)
    {
       this.someField3 = someField3;
       this.someField4 = someField4;
    }
    companion object
    {
        @JvmField val CREATOR = PaperParcelDoge.CREATOR
    }
    //end of PaperParcel stuff.

    constructor(data:JSON):super(data)
    {
       //parse data to set the fields.
    }
}

1 个答案:

答案 0 :(得分:3)

如上所述here,您的属性应在主构造函数中声明。

  

Parcelable支持

     

Android Extensions插件现在包含一个自动   可分配的实现生成器。声明序列化属性   在主构造函数中添加@Parcelize注释,和   将创建writeToParcel()/ createFromParcel()方法   自动:

@Parcelize
class User(val firstName: String, val lastName: String) : Parcelable