【问题标题】:Suspension functions can be called only within coroutine body挂起函数只能在协程体内调用
【发布时间】:2021-06-05 18:52:32
【问题描述】:

我检查了其他问题,但似乎都没有解决我的问题。 我的HomeViewModel 中有两个suspend funs,我在HomeFragment 中调用它们(带有微调器文本参数)。

HomeViewModel中的两个挂起函数:

suspend fun tagger(spinner: Spinner){
       withContext(Dispatchers.IO){
           val vocab: String = inputVocab.value!!
           var tagger = Tagger(
                   spinner.getSelectedItem().toString() + ".tagger"
           )
           val sentence = tagger.tagString(java.lang.String.valueOf(vocab))
           tagAll(sentence)
       }
    }


    suspend fun tagAll(vocab: String){
       withContext(Dispatchers.IO){
           if (inputVocab.value == null) {
               statusMessage.value = Event("Please enter sentence")
           }
           else {
               insert(Vocab(0, vocab))
               inputVocab.value = null
           }
       }
    }

这就是我在HomeFragment 中称呼它们的方式:

GlobalScope.launch (Dispatchers.IO) {
        button.setOnClickListener {
            homeViewModel.tagger(binding.spinner)
        }
    }

tagger 我收到错误“只能在协程主体内调用暂停函数”。但它已经在全球范围内。如何避免这个问题?

【问题讨论】:

    标签: android kotlin kotlin-coroutines


    【解决方案1】:

    但它已经在全局范围内。

    button.onSetClickListener() 的调用是在从CoroutineScope 启动的协程中。但是,您传递给 onSetClickListener() 的 lambda 表达式是一个单独的对象,映射到一个单独的 onClick() 函数,并且 那个 函数调用不是该协程的一部分。

    您需要将其更改为:

        button.setOnClickListener {
            GlobalScope.launch (Dispatchers.IO) {
                homeViewModel.tagger(binding.spinner)
            }
        }
    

    顺便说一句,您不妨查看Google's best practices for coroutines in Android,尤其是"The ViewModel should create coroutines"

    【讨论】:

    • 再次感谢您!特别是对于指南链接
    猜你喜欢
    • 2020-11-18
    • 2020-11-07
    • 2019-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-03
    • 2020-06-27
    相关资源
    最近更新 更多