kotlin - 调用 Continuation.resumeX() 失败一定是个问题吗?
问题描述
我suspendCoroutine
用来避免在Dialog
s 中使用回调。但是,在 Android 中,当对话框关闭时(通过单击对话框区域外),Dialog
没有明显的地方可以调用。Continuation.resume()
如果您尝试调用,Dialog.setOnDismissListener()
则必须跟踪是否已在按钮侦听器中调用了 resume。
suspend fun displayDialog() = suspendCoroutine<String?> { continuation ->
val builder = AlertDialog.Builder(context)
builder.setCancelable(true)
builder.setNegativeButton(android.R.string.cancel) { _, _ ->
continuation.resume(null)
}
builder.setPositiveButton(android.R.string.ok) { _, _ ->
continuation.resume("it's ok")
}
val dialog = builder.show()
dialog.setOnDismissListener {
// if the user clicked on OK, then resume has already been called
// and we get an IllegalStateException
continuation.resume(null)
}
}
那么,是否更好地跟踪是否已经调用了 resume(以避免再次调用它),或者只是不打扰resume(null)
调用(在 onDismissListener 中)?
解决方案
Continuation 是一个低级原语,只能恢复一次,因此您必须resume
在使用它时跟踪是否已经调用过它。或者,您可以使用更高级别的通信原语,例如CompletableDeferred
,它具有多用途complete
功能:
suspend fun displayDialog(): String? {
val deferred = CompletableDeferred<String?>()
val builder = AlertDialog.Builder(context)
builder.setCancelable(true)
builder.setNegativeButton(android.R.string.cancel) { _, _ ->
deferred.complete(null)
}
builder.setPositiveButton(android.R.string.ok) { _, _ ->
deferred.complete("it's ok")
}
val dialog = builder.show()
dialog.setOnDismissListener {
deferred.complete(null)
}
return deferred.await()
}
推荐阅读
- excel - 通过 Excel VBA 取消保护/保护 Word 文档
- reactjs - componentWillUnmount 没有清除超时
- c# - Xamarin.Forms DatePickerCustomRenderer 无法识别 IOnDateSetListener
- python - 如果我们有编辑器,我们在 pycharm(或任何 IDE)中需要什么 python cosole?反之亦然
- python - Python 全局和局部变量:代码是如何工作的?
- python - 如何计算 Tensorflow BigQuery ReadSession 的“对表合理的并行量”?
- azure-data-factory - ADF:如何清除 SQL 中的表?
- cypress - cypress 下载:“cypress run”似乎与“cypress open”相同
- bing-maps - Bing Truck Routing API - travelDistance 单位
- windows - mingw ld 找不到-lpthread?