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