我想在使用 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】:

看看withTimeoutOrNulldocumentation:

在指定超时的协程内运行给定的暂停代码块,如果超过此超时,则返回 null

这意味着您的translateList 函数需要暂停函数。

这里有一口井tutorial解释如何将回调函数转换为挂起函数。

【讨论】:

以上是关于我想在使用 kotlin 协程的 android 超时后取消一个函数,但它不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Kotlin协程的原理,没有说得比AndroidDeveloper官方更显浅的了

kotlin协程的理解

使用协程的 Kotlin/Native 多线程

使用 Kotlin 协程的 Spring Boot Rest 服务

史上最详Android版kotlin协程入门进阶实战

kotlin 协程最佳实践-android官网