在 Android 中实现状态恢复时,如何保存和恢复 lambda?
我尝试将其保存为 Serializable 和 Parcelable,但它会引发编译错误。
有什么方法可以保存和恢复它们,还是我应该寻求其他方法?
最佳答案
Kotlin lambda 实现 Serializable
,所以它们不能像这样保存:
override fun onSaveInstanceState(outState: Bundle) {
outState.putSerializable("YOUR_TAG", myLambda as Serializable)
super.onSaveInstanceState(outState)
}
同样,要恢复它们:
override fun onCreate(savedInstanceState: Bundle?) {
myLambda = savedInstanceState?.getSerializable("YOUR_TAG") as (MyObject) -> Void
super.onCreate(savedInstanceState)
}
(这显然可以在任何为您提供
savedInstanceState
的生命周期事件中完成,因为这只是一个示例)一些注意事项:
import java.io.Serializable
是必须的。 Unchecked cast: Serializable? to YourLambdaType
.这个强制转换是安全的(假设你正确地推断出可空性!),所以你可以通过使用 @Suppress("UNCHECKED_CAST")
安全地抑制这个警告。 MyObject
必须是 Serializable
或 Parcelable
,否则它会在运行时崩溃。 现在有一个细节在任何地方都没有被告知,并且在运行时崩溃并且没有有用的崩溃日志。 lambda 的内部实现(即分配它时
{ }
中的内容)不能引用稍后将被释放的对象。一个经典的例子是:
// In your MyActivity.kt…
myLambda = { handleLambdaCallback() }
…
private fun handleLambdaCallback() {
…
}
这将在运行时崩溃,因为
handleLambdaCallback
正在隐式访问 this
,这将触发递归序列化它可访问的整个对象图的尝试,这将在序列化时间的某个时间点失败。解决此问题的一种方法是在 lambda 中发送引用。例子:
// In your MyActivity.kt…
myLambda = { fragment -> (fragment.activity as MyActivity).handleLambdaCallback() }
…
private fun handleLambdaCallback() {
…
}
这样,我们在调用 lambda 时计算引用,而不是在分配时计算引用。绝对不是最干净的解决方案,但它是我能想到的最好的解决方案,而且它有效。
随意提出改进和替代解决方案!
关于android - 如何在 Android 中保存和恢复 lambda?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53939560/