Kotlin android 可打包

问题描述 投票:0回答:4

我已经使用了 android studio 的 android 插件的自动生成功能,它生成了以下代码,但我不明白为什么

final val
字段需要
CREATOR
?我第一次在 kotlin 中看到
final
关键字。

data class Person(
        val name: String,
        val surname: String
) : Parcelable {
    constructor(source: Parcel): this(source.readString(), source.readString())

    override fun describeContents(): Int {
        return 0
    }

    override fun writeToParcel(dest: Parcel?, flags: Int) {
        dest?.writeString(name)
        dest?.writeString(surname)
    }

    companion object {
        @JvmField final val CREATOR: Parcelable.Creator<Person> = object : Parcelable.Creator<Person> {
            override fun createFromParcel(source: Parcel): Person {
                return Person(source)
            }

            override fun newArray(size: Int): Array<Person?> {
                return arrayOfNulls(size)
            }
        }
    }
}
java android kotlin parcel
4个回答
8
投票

在 Kotlin 中类和成员默认是最终的。换句话说,以下声明具有相同的字节码:

@JvmField final val CREATOR: Parcelable.Creator<Person> = PersonCreator()
@JvmField val CREATOR: Parcelable.Creator<Person> = PersonCreator()

因此,虽然生成的代码具有

final
关键字并且它不是错误,但它是多余的。

尽管默认情况下类和成员是最终的,但在 Kotlin 中仍然需要

final
修饰符。一个示例是在派生类中将
open
方法标记为
final

open class Base {
    open fun test(){}
}

open class DerivedA : Base(){
    final override fun test(){}
}

class DerivedB : DerivedA() {
    override fun test(){} //error: 'test' in 'DerivedA' is final and cannot be overriden
}

虽然在 java 中制作

public static
字段
final
是一个很好的做法,但 对于
Parccelable.Creator
字段
没有严格要求标记为这样:

实现 Parcelable 接口的类还必须具有 称为 CREATOR 的非空静态字段,其类型实现 Parcelable.Creator 接口。


7
投票

在 Kotlin 中,您可以使用

@Parcelize
Kotlin Android 扩展:

@Parcelize
data class User(val id: String, val name: String) : Parcelable

这是一个编译器插件,可以自动为您生成 Parcelable 实现。

Kotlin 文档上的

此页面提供了更多详细信息,包括要求、支持的类型以及如何为不支持的类型创建自定义包裹器


如果您好奇并想深入了解实现的技术细节,请参阅 Kotlin 演进和增强过程 支持编译器扩展

android.os.Parcelable


此功能在 Kotlin 1.3.40 之前一直处于实验阶段。如果您仍在使用 1.3.40 之前的 Kotlin 版本,则需要启用实验性功能才能使用此功能:

android { // Enable @Parcelize // You only need this for Kotlin < 1.3.40 androidExtensions { experimental = true } ... }
    

2
投票
对数据类使用@Parcelize注解并扩展Parcelable。 Kotlin 会自动为您完成剩下的工作。示例-人员数据类。

@Parcelize data class Person(val name: String, val age: Int, val email: String) : Parcelable

您可以发送值,让我们在活动中按下按钮,如下所示。

private val PERSON = "person" // first ensure a person object with data val person = Person("Shihab Uddin", 30, "[email protected]") binding.buttonSend.setOnClickListener { val intent = Intent(this, ReceiveParcelableAcitivty::class.java) //then put an parcelable extra to intent intent.putExtra(PERSON, person) startActivity(intent) }

Receiver 活动将获取类似

的数据

private val PERSON = "person" intent?.let { var person = intent.extras.getParcelable(PERSON) as Person bind.textViewData.text = " Data Receive: $person" }

androidExtensions 属性不再需要 < kotlin 1.3.40

android { // You only need this for Kotlin < 1.3.40 androidExtensions { experimental = true } ... }
    

0
投票
您需要添加

plugins { id("kotlin-parcelize") }
在此文件中

build.gradle.kts


现在,你可以使用它了。

import kotlinx.parcelize.Parcelize @Parcelize data class User(val id: String, val name: String) : Parcelable
    
© www.soinside.com 2019 - 2024. All rights reserved.