Oya*_*nlı 4 android callback cancellation kotlin-coroutines
我在 suspendCancellableCoroutine 中包装了一个回调,将其转换为挂起函数:
suspend fun TextToSpeech.speakAndWait(text: String) : Boolean {
val uniqueUtteranceId = getUniqueUtteranceId(text)
speak(text, TextToSpeech.QUEUE_FLUSH, null, uniqueUtteranceId)
return suspendCancellableCoroutine { continuation ->
this.setOnUtteranceProgressListener(object : JeLisUtteranceProgressListener() {
override fun onDone(utteranceId: String?) {
if(utteranceId == uniqueUtteranceId) {
Timber.d("word is read, resuming with the next word")
continuation.resume(true)
}
}
})
}
}
Run Code Online (Sandbox Code Playgroud)
我使用片段的生命周期作用域协程范围调用此函数,并且我假设在片段被销毁时它被取消。然而,LeakCanary 报告说,由于这个监听器,我的片段正在泄漏,并且我通过日志验证了即使在协程被取消之后,回调仍然被调用。
所以看来用 suspendCancellableCoroutine 而不是 suspendCoroutine 包装不足以取消回调。我想我应该主动检查该作业是否处于活动状态,但是如何呢?我尝试coroutineContext.ensureActive()检查coroutineContext.isActive回调内部,但 IDE 给出错误,指出“只能在协程体内调用暂停函数”。我还能做些什么来确保作业被取消时它不会恢复?
LeakCanary 报告说,由于这个监听器,我的片段正在泄漏,并且我通过日志验证了即使在协程被取消之后,回调仍然被调用。
是的,底层异步 API 不知道 Kotlin 协程,您必须使用它来显式传播取消。KotlininvokeOnCancellation专门为此提供了回调:
return suspendCancellableCoroutine { continuation ->
this.setOnUtteranceProgressListener(object : JeLisUtteranceProgressListener() {
/* continuation.resume() */
})
continuation.invokeOnCancellation {
this.setOnUtteranceProgressListener(null)
}
}
Run Code Online (Sandbox Code Playgroud)
如果您想删除JeLisUtteranceProgressListener无论结果如何(成功、取消或其他错误),您可以使用经典的 try/finally 块:
suspend fun TextToSpeech.speakAndWait(text: String) : Boolean {
val uniqueUtteranceId = getUniqueUtteranceId(text)
speak(text, TextToSpeech.QUEUE_FLUSH, null, uniqueUtteranceId)
return try {
suspendCancellableCoroutine { continuation ->
this.setOnUtteranceProgressListener(object : JeLisUtteranceProgressListener() {
override fun onDone(utteranceId: String?) {
if(utteranceId == uniqueUtteranceId) {
Timber.d("word is read, resuming with the next word")
continuation.resume(true)
}
}
})
} finally {
this.setOnUtteranceProgressListener(null)
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10882 次 |
| 最近记录: |