android - 当回调是类的字段时,将回调转换为suspendCoroutine
问题描述
我想将一些基于回调的 3rd-party API 转换为易于使用的简单挂起函数。这是我的实现的简化示例。
class LibraryWrapper {
private lateinit var onFooFired: (Boolean) -> Unit
private val libraryCallback = object : LibraryCallback {
override fun foo(result: Boolean) {
onFooFired(result)
}
}
private val library = Library(libraryCallback)
suspend fun bar(): Boolean {
return suspendCoroutine { performingBar: Continuation<Boolean> ->
onFooFired = {fooResult -> performingBar.resume(fooResult) }
library.bar()
}
}
}
但这种解决方案有时有效,有时无效。这个 lambda 字段存在这样的问题,有时它会正确初始化,但有时会抛出异常“lateinit property onFooFired is not initialized”。
这很奇怪,因为我确实在运行 library.bar() 之前对其进行了初始化,并且仅在调用library.bar() 之后才调用 LibraryCallback 的 foo 。
解决方案
首先,我认为当您不控制字段的初始化时,使用“lateinit var”不是一个好方法。仅当您有初始化的承诺时才使用 lateinit。
尝试使用可为空的字段实现,例如
private var onFooFired: ((Boolean) -> Unit)? = null
并在回调中:
private val libraryCallback = object : LibraryCallback {
override fun foo(result: Boolean) {
onFooFired?.invoke(result)
}
}
在这种情况下,除非您没有实现“onFooFired” lambda,否则它不会调用
推荐阅读
- javascript - Leaflet.Draw 使用 GeoJson 保存数据
- bash - 将单行 Mac bash 脚本转换为单行 cmd.exe 行
- r - tryCatch 函数适用于大多数不存在的 URL,但它在(至少)一种情况下不起作用
- javascript - 如何仅使用 javascript 基于数组索引上传图像?
- mysql - 查询以统计名称中包含“学院”一词的机构数量
- c - 如何使用空指针创建和打印动态字符数组?(初学者)
- c - 为什么 C 不能正确计算模数,尽管如此结果是正确的?
- c - 如果条件为真,则使用函数不工作?
- javascript - 如何从 html 按钮更改 javascript 布尔值?
- javascript - 更改的文本文件,像幻灯片一样显示?