我想在使用 kotlin 协程的 android 超时后取消一个函数,但它不起作用
Posted
技术标签:
【中文标题】我想在使用 kotlin 协程的 android 超时后取消一个函数,但它不起作用【英文标题】:I want to cancel a function after a timeout on android with kotlin coroutines but it doesn't work 【发布时间】:2021-01-13 21:59:47 【问题描述】:我想做的是用谷歌云翻译翻译一个文本列表,这是可行的,但有时速度很慢。所以 10 秒后我想取消它并使用 withTimeoutOrNull 块,但它不会取消它即使在超时后仍然运行的操作。
lifecycleScope.launch
withContext(Dispatchers.IO)
var imageClassesListInHungarian = listOf<String>()
withTimeoutOrNull(10000)
imageClassesListInHungarian = translateList(
imageClassesList,
"hu",
resources
)
// cannot be cancelled but I don't know why
...
fun translateList(originalTextsList: List<String>, targetLanguage: String, resources: Resources): List<String>
val translatedTextsList = mutableListOf<String>()
try
val translate = getTranslateService(resources)
val translation = translate?.translate(originalTextsList, Translate.TranslateOption.targetLanguage(targetLanguage), Translate.TranslateOption.model("base"))
if (translation != null)
for(t in translation)
translatedTextsList.add(t.translatedText)
catch (e: TranslateException)
e.printStackTrace()
return translatedTextsList
【问题讨论】:
为了使超时工作,withTimeout
块内的函数调用必须是与取消配合的挂起函数。如果 API 没有提供用于进行异步调用的 Kotlin 挂起函数,您可以使用 suspendCancellableCoroutine
创建自己的。但我不熟悉谷歌云翻译,不知道你可以用什么来构建它。
Coroutine cancellation is cooperative您的同步代码块不会被中断,因为它不知道其运行的协程范围已被取消。
【参考方案1】:
看看withTimeoutOrNull
documentation:
在指定超时的协程内运行给定的暂停代码块,如果超过此超时,则返回 null
这意味着您的translateList
函数需要暂停函数。
这里有一口井tutorial解释如何将回调函数转换为挂起函数。
【讨论】:
以上是关于我想在使用 kotlin 协程的 android 超时后取消一个函数,但它不起作用的主要内容,如果未能解决你的问题,请参考以下文章
Kotlin协程的原理,没有说得比AndroidDeveloper官方更显浅的了