53

我正在从 onCreate(...) 调用挂起函数

override fun onCreate(savedInstanceState: Bundle?) {
    ...
    ...
    callGetApi()
}

和暂停的功能是: -

suspend fun callGetApi() {....}

但是错误显示暂停函数'callGetApi'应该只从协程或另一个暂停函数中调用

4

3 回答 3

53

挂起函数只能从协程中调用。这意味着您需要使用协程构建器,例如launch. 例如:

class Activity : AppCompatActivity(), CoroutineScope {
    private var job: Job = Job()

    override val coroutineContext: CoroutineContext
        get() = Dispatchers.Main + job

    override fun onDestroy() {
        super.onDestroy()
        job.cancel()
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        launch {
            val result =  callGetApi()
            onResult(result) // onResult is called on the main thread
        }
    }

    suspend fun callGetApi(): String {...}

    fun onResult(result: String) {...}
}

Dispatchers.Main在 Android 中使用,请将依赖项添加到应用程序的build.gradle文件中:

implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.0.1'

更好的方法是在ViewModelActivity/中使用扩展属性Fragment

它附加到协程的生命周期Activity/Fragment并在它们销毁时取消已启动的协程。

于 2018-12-26T07:30:55.970 回答
33

截至2019 年 7 月,看起来最优雅的方式是这里描述的方式:

import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.launch

class Activity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super...

        lifecycleScope.launch {
            val result =  callGetApi()
            onResult(result) 
        }
    }
}

不要忘记添加相应的库:

implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.2.0-alpha02"
于 2019-07-24T03:10:54.170 回答
9

上面的答案有效,但我解决了它而没有继承CoroutineScope类,只使用.... gradle.build

  dependencies {
      implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.3'
  }

活动.kt

  import kotlinx.coroutines.GlobalScope
  import kotlinx.coroutines.Dispatchers

  GlobalScope.launch (Dispatchers.Main) { callGetApi() }

Dispatchers.Main很重要,因为您不能在除主线程之外的任何其他线程中更新 UI。

但是它建议继承 CoroutineScope 来维护活动的生命周期和onDestroy杀死工作的活动的生命周期

于 2018-12-26T07:49:19.823 回答