有没有办法在 Android savedInstanceState Bundle 中使用 Kotlinx 序列化?

Is there a way to use Kotlinx serialisation in an Android savedInstanceState Bundle?

看起来编译器不想在 putSerializablegetSerializable 中使用 Kotlinx 序列化 类。 它说 Type mismatch: inferred type is MyViewModel.SavedState but Serializable? was expected.

在我的 Activity:

override fun onCreate(savedInstanceState: Bundle?) {
    AndroidInjection.inject(this)
    super.onCreate(savedInstanceState)

    setContentView(R.layout.my_activity_layout)

    viewModel.init(savedInstanceState?.getSerializable(SAVE_STATE) as? SavedState) // compiler complains here
}

override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    outState.putSerializable(SAVE_STATE, viewModel.buildSaveState()) // and here
}

在我的 ViewModel 中:

fun buildSaveState(): SavedState =
        SavedState(value1, value2, value3, value4)

@Serializable
data class SavedState(val foo: Boolean?,
                      val foo1: Enum1?,
                      val foo2: Enum2?,
                      val foo3: MyType?)

我的类型:

@Serializable
sealed class MyType {
    data class MyType1(val foo4: Enum3) : MyType()
    data class MyType2(val foo5: Enum4) : MyType()

    enum class Enum3 {
        ...
    }

    enum class Enum4 {
        ...
    }
}

我很确定 Kotlinx.Serialization 与 Bundle 的 putSerializable 不兼容。但是,您可以 stringify 您的 SavedState,通过 putString 发送它,并在接收端将字符串反序列化回您的 class.

您可以使用 kotlin-parcelize 插件 (https://developer.android.com/kotlin/parcelize)

首先将插件添加到您的app/build。gradle:

plugins {
    ..
    id 'kotlin-parcelize'
}

然后将@Parcelize注解和Parcelable接口添加到class:

import kotlinx.parcelize.Parcelize

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

然后您可以将实例添加到包中:

val user = User("John", "Doe", 33)
bundle.putParcelable("mykey", user)

但是,kotlin-parcelize 插件似乎不适用于密封的 classes,因此它可能不是您用例的正确解决方案。