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

Dam*_*les 6 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
Run Code Online (Sandbox Code Playgroud)

我怎么解决这个问题?我应该用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.
    }
}
Run Code Online (Sandbox Code Playgroud)

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.
    }
}
Run Code Online (Sandbox Code Playgroud)

Ben*_*min 6

如前所述在这里,你的属性应该将主构造函数内部声明。

可包裹支持

Android 扩展插件现在包含一个自动 Parcelable 实现生成器。在主构造函数中声明序列化属性并添加@Parcelize 注解,并会自动创建 writeToParcel()/createFromParcel() 方法:

@Parcelize
class User(val firstName: String, val lastName: String) : Parcelable
Run Code Online (Sandbox Code Playgroud)