59 votes

La fonction de suspension 'callGetApi' ne doit être appelée qu'à partir d'une coroutine ou d'une autre fonction de suspension

J'appelle la fonction suspendue de onCreate (...)

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

et la fonction suspendue est: -

 suspend fun callGetApi() {....}

Mais l'erreur apparaît La fonction de suspension 'callGetApi' ne doit être appelée qu'à partir d'une coroutine ou d'une autre fonction de suspension

65voto

Serg_ Points 12

La fonction Suspend ne doit être appelée qu'à partir de coroutine. Cela signifie que vous devez utiliser un constructeur de coroutine, par exemple launch . Par example:

 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) {...}
}

Pour utiliser Dispatchers.Main dans Android, ajoutez une dépendance au fichier build.gradle

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

39voto

Kipr Points 422

On dirait que la façon la plus élégante de le faire à partir de juillet 2019 est celle décrite ici :

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

class Activity : AppCompatActivity() {

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

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

N'oubliez pas d'ajouter la bibliothèque correspondante:

 implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.2.0-alpha02"

9voto

Santanu Sur Points 5061

La réponse ci-dessus a fonctionné, mais je l'ai résolue sans hériter de la CoroutineScope en utilisant simplement .... gradle.build

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

Activity.kt

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

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

Dispatchers.Main est important car vous ne pouvez pas mettre à jour l'interface utilisateur dans un autre thread que main.

Mais il est recommandé d'hériter de CoroutineScope pour maintenir le cycle de vie de l'activité et onDestroy de l'activité pour tuer le travail

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X