如何使用Kotlin@Parcelize从地块创建?

8iwquhpp  于 2023-01-13  发布在  Kotlin
关注(0)|答案(4)|浏览(209)

我正在尝试将可打包模型从Java迁移到Kotlin。
我的模型如下所示:

import kotlinx.parcelize.*

@Parcelize
class SignatureAuthorityModel
    (var id: Int,
    var cloudId: Int,
    var uuid: UUID?): android.os.Parcelable
{
    override fun equals(other: Any?): Boolean
    {
        //equals implementation
    }

    override fun hashCode(): Int
    {
       //some hash implementation
    }

    override fun toString(): String
    {
       //some stringifier implementation
    }
}

我可以为此模型调用writeToParcel,但是SignatureAuthorityModel.createFromParcel(包裹)不可用。我必须单独编写它吗?还是必须以某种方式配置kotlin-parcelize插件?从kotlin文档来看,当我使用@Parcelize注解时,createFromParcel也应该自动生成,并且只有当我有一些高级逻辑时,我才必须在伴随对象创建器中编写实现。正确的方法是什么?

sr4lhrrt

sr4lhrrt1#

如果你使用的是@Parcelize注解,那么你不需要写createFromParcel方法,因为@Parcelize在内部管理createFromParcel方法。
就像下面这样写你的数据类。可能你错误的导入了Parcelable,你的类应该像下面这样。

import kotlinx.parcelize.Parcelize

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

hkmswyz62#

根据this pull request,有一种方法可以访问CREATOR,同时仍然使用@Parcelize注解。我无法发现如何仅阅读PR或文档。
不过,我还是设法找到了(在PR中)一个令人愉快的小函数,到目前为止它是成功的。我很容易地将它复制并粘贴到我的项目中。调用它将返回一个CREATOR,然后您可以从中调用createFromParcel(parcel)

public inline fun <reified T : Parcelable> parcelableCreator(): Parcelable.Creator<T> =
T::class.java.getDeclaredField("CREATOR").get(null) as? Parcelable.Creator<T>
    ?: throw IllegalArgumentException("Could not access CREATOR field in class ${T::class.simpleName}")

下面是它在一个简单测试中的用法示例,该测试先打包,然后从打包创建。

@Test
fun `UserDto parcelizes then unparcelizes`() {
    val parcel = Parcel.obtain()
    inputUserDto.writeToParcel(parcel, 0)
    parcel.setDataPosition(0)

    val userDtoFromParcel = parcelableCreator<UserDto>().createFromParcel(parcel)

    assertThat(inputUserDto).isEqualTo(userDtoFromParcel)
}

这里有一个链接,我在这里找到了helper内联函数。它可能不是在所有情况下都能工作,但到目前为止,它对我来说很好。

qgelzfjb

qgelzfjb3#

使用@Parcelize时无法访问创建者似乎是一个已知问题
查看5年前创建的此期:https://youtrack.jetbrains.com/issue/KT-19853
根据那里的评论,他们似乎没有做任何事情。
我个人认为,他们可能不会为此烦恼,因为对于最常见的用例来说,这是不必要的。在Android开发中,Parcelable最常见的用例是使用intent.putExtra()intent.putParcelableArrayListExtra()将对象从一个Activity传递到另一个Activity,在这种情况下,转换为Parcel并返回会自动发生。
编辑:
嗯......实际上,他们在这里提到https://github.com/JetBrains/kotlin/pull/4575,它应该可以使用parcelableCreator,但我不知道如何使用它,或者它是否实际上是最新版本

6ioyuze2

6ioyuze24#

要检索由@Parcelize注解的Parcelable类中的CREATOR,只需使用正确的类型信息调用parcelableCreator

@Parcelize
data class MyParcelableClass(val someField: String): Parcelable

// getting Creator for this Parcelable
val creator = parcelableCreator<MyParcelableClass>()

相关问题