我应该在build.gradle文件中进行哪些更改或导入类以在带有Kotlin 1.3的Android项目中使用稳定的协程函数?

我的build.gradle中有关协程的 fragment
implementation "org.jetbrains.kotlin:kotlin-coroutines-core:$coroutines_version"implementation "org.jetbrains.kotlin:kotlin-coroutines-android:$coroutines_version"
我当然使用Android Studio 3.3预览版

最佳答案

build.gradle中将库更改为
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.1'

删除(如果已添加):

kotlin {
    experimental {
        coroutines "enable"
    }
}

在代码中,将launch更改为GlobalScope.launch(Dispatchers.IO)GlobalScope.launch(Dispatchers.Main)

更新

请使用局部协程上下文而不是全局范围(例如,参见http://kotlinlang.org/docs/reference/coroutines/coroutine-context-and-dispatchers.html)。

用于 Activity

参见https://github.com/Kotlin/kotlinx.coroutines/blob/master/ui/coroutines-guide-ui.md

实现CoroutineScope:
class YourActivity : AppCompatActivity(), CoroutineScope {

添加本地变量job并将其初始化:
private lateinit var job: Job

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

    job = Job()
}

创建一个协程上下文并在Activity destroy上将其取消:
override fun onDestroy() {
    job.cancel()
    super.onDestroy()
}

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

用于 fragment (与Activity中的相同)

实现CoroutineScope:
class YourFragment : Fragment(), CoroutineScope {

创建一个局部变量job,并在onCreate()中对其进行初始化。 (我尝试编写private val job: Job = Job(),但遇到了一个问题,即在ViewPager中您将创建Fragment和它们的作业。由于我们将在刷入job的过程中取消onDestroy()中的ViewPager,因此我们应该重新创建作业)。
private lateinit var job: Job

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

    ...
    job = Job()
}

创建一个协程上下文,并在Fragment destroy上将其取消:
override val coroutineContext: CoroutineContext
    get() = Dispatchers.Main + job // You can use different variants here.

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

一个启动示例

照常使用launch:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    launch {
        // Wait for result of I/O operation without blocking the main thread.
        withContext(Dispatchers.IO) {
            interactor.getCountry().let {
                countryName = it.name
            }
        }

        // Update views in the UI thread.
        country.updateCaption(countryName)
    }
}

就我而言,当我将API请求与常规回调一起使用时,出现了问题。尚未调用回调内部的launch内部。因此,我用交互器重写了该代码。

10-05 21:31