我应该在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
内部。因此,我用交互器重写了该代码。