How to migrate Kotlin from 1.2 to Kotlin 1.3.0 then using async, UI, and bg in a presenter function

you must use GlobalScope.launch instead of launch ,GlobalScope.async instead of async Dispatcher.main instead of UI

coroutineBasics


Your code has several layers of problems:

  1. You're using async, but you don't await on it. You should be using launch instead.
  2. You're using the pre-coroutines facility of bg, equivalent to async
  3. You immediately await on bg, which means you should be using withContext(Default) instead
  4. (new with Kotlin 1.3) You aren't applying structured concurrency

This is how your code should look in Kotlin 1.3:

fun CoroutineScope.getTeamList(league: String?) {
    view.showLoading()
    this.launch {
        val data = withContext(Dispatchers.IO) {
            gson.fromJson(apiRepository.doRequest(TheSportDBApi.getTeams(league)),
                    TeamResponse::class.java
            )
        }
        view.showTeamList(data.teams)
        view.hideLoading()
    }
}

You should call your function with the coroutine scope appropriate to your situation. A typical approach is tying it to your activity:

class MyActivity : AppCompatActivity(), CoroutineScope {
    lateinit var masterJob: Job
    override val coroutineContext: CoroutineContext
        get() = Dispatchers.Main + masterJob

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        masterJob = Job()
    }

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

Also add

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

Here is a fix ( I don't know if it is the best way to do it) :

import com.google.gson.Gson
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.launch

class TeamsPresenter(private val view: TeamsView,
                     private val apiRepository: ApiRepository,
                     private val gson: Gson
) {
    fun getTeamList(league: String?) {
        view.showLoading()
        CoroutineScope(Dispatchers.Main).launch {
            val data = async {
                gson.fromJson(apiRepository
                    .doRequest(TheSportDBApi.getTeams(league)),
                    TeamResponse::class.java
                )
            }
            view.showTeamList(data.await().teams)
            view.hideLoading()
        }
    }
}