Suspend function ‘callGetApi’ should be called only from a coroutine or another suspend function

Suspend function should be called only from a coroutine.

That means to call a suspend function you need to use a coroutine builder, e.g. launch, async or runBlocking(recommended to use only in unit tests). For 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) {...}
}

To use Dispatchers.Main in Android add dependency to the app’s build.gradle file:

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

The MOST RECENT APPROACH would be to use extension properties in ViewModel and Activity/Fragment:

  • In ViewModel we can use viewModelScope to launch a coroutine:

    viewModelScope.launch { ... }
    

It attached to the lifecycle of Activity/Fragment and cancels launched coroutines when they destroyed.

  • Similar in Activity/Fragment we can use the following extension properties to launch a coroutine:
    lifecycleScope.launch {}, lifecycle.coroutineScope.launch {}, viewLifecycleOwner.lifecycleScope.launch {}(applicable in Fragments).

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)