如何将Kotlin从1.2迁移到Kotlin 1.3.0然后在演示者函数中使用async,UI和bg

Dik*_*ika 6 kotlin kotlin-coroutines

我在Kotlin项目中使用MVP模式.我有一个Presenter类:

import com.google.gson.Gson
import kotlinx.coroutines.experimental.android.UI
import kotlinx.coroutines.experimental.async
import org.jetbrains.anko.coroutines.experimental.bg

class TeamsPresenter(private val view: TeamsView,
                     private val apiRepository: ApiRepository,
                     private val gson: Gson
) {
    fun getTeamList(league: String?) {
        view.showLoading()

        async(UI){
            val data = bg {
                gson.fromJson(apiRepository
                    .doRequest(TheSportDBApi.getTeams(league)),
                    TeamResponse::class.java
                )
            }
            view.showTeamList(data.await().teams)
            view.hideLoading()
        }
    }   
}
Run Code Online (Sandbox Code Playgroud)

这个演示者课程在Kotlin 1.2.71上正常工作,但我无法在Kotlin 1.3.0上工作.

我在项目的build.gradle中更新了Kotlin版本,删除了"实验协同程序"并添加了kotlin coroutine core依赖:

implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.0.0'
Run Code Online (Sandbox Code Playgroud)

这是我目前的代码:

import com.google.gson.Gson

class TeamsPresenter(private val view: TeamsView,
                     private val apiRepository: ApiRepository,
                     private val gson: Gson
) {
    fun getTeamList(league: String?) {
        view.showLoading()

        async(UI){
            val data = bg {
                gson.fromJson(apiRepository
                    .doRequest(TheSportDBApi.getTeams(league)),
                    TeamResponse::class.java
                )
            }
            view.showTeamList(data.await().teams)
            view.hideLoading()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

主要在异步,UI和bg函数上出错:

unresolved reference: async
unresolved reference: UI
unresolved reference: bg
Run Code Online (Sandbox Code Playgroud)

如何在Kotlin 1.3.0上使用它?如有任何帮助,请提前感谢.

Kou*_*osh 5

您必须使用GlobalScope.launch而不是launch,GlobalScope.async而不是async Dispatcher.main而不是UI

协程基础


Mar*_*nik 3

您的代码有几层问题:

  1. 你正在使用async,但你没有await使用它。你应该改用launch
  2. 您正在使用 的预协程设施bg,相当于async
  3. 您立即await打开bg,这意味着您应该withContext(Default)使用
  4. (Kotlin 1.3 的新功能)您没有应用结构化并发

您的代码在 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()
    }
}
Run Code Online (Sandbox Code Playgroud)

您应该使用适合您情况的协程范围来调用您的函数。典型的方法是将其与您的活动联系起来:

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()
    }
}
Run Code Online (Sandbox Code Playgroud)