使用Kotlin 1.3在Android中迁移到Kotlin协程
我应该在我的build.gradle
文件中进行哪些更改或导入类以在带有Kotlin 1.3的Android项目中使用稳定的协程函数?
What should I change in my build.gradle
file or import in classes to use stable coroutine functions in my Android project with Kotlin 1.3 ?
我的build.gradle
implementation "org.jetbrains.kotlin:kotlin-coroutines-core:$coroutines_version"
implementation "org.jetbrains.kotlin:kotlin-coroutines-android:$coroutines_version"
implementation "org.jetbrains.kotlin:kotlin-coroutines-core:$coroutines_version"
implementation "org.jetbrains.kotlin:kotlin-coroutines-android:$coroutines_version"
我当然使用Android Studio 3.3预览
Of course I use Android Studio 3.3 Preview
在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 ).
Please, use local coroutine context instead of global scope (see, for instance, http://kotlinlang.org/docs/reference/coroutines/coroutine-context-and-dispatchers.html).
活动
请参见 https://github.com /Kotlin/kotlinx.coroutines/blob/master/ui/coroutines-guide-ui.md .
实施CoroutineScope
:
class YourActivity : AppCompatActivity(), CoroutineScope {
添加局部变量job
并将其初始化:
Add a local variable job
and initialize it:
private lateinit var job: Job
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
job = Job()
}
创建一个协程上下文并在Activity销毁时将其取消:
Create a coroutine context and cancel it on Activity destroy:
override fun onDestroy() {
job.cancel()
super.onDestroy()
}
override val coroutineContext: CoroutineContext
get() = Dispatchers.Main + job
对于片段(与Activity
中的相同)
实施协程范围:
class YourFragment : Fragment(), CoroutineScope {
创建一个局部变量job
,并在onCreate()
中对其进行初始化. (我尝试编写private val job: Job = Job()
,但遇到了一个问题,即在ViewPager
中您将创建Fragment
s及其作业.由于我们将在ViewPager
中刷卡时取消onDestroy()
中的job
重新创建工作).
Create a local variable job
and initialize it in onCreate()
. (I tried to write private val job: Job = Job()
, but bumped into problem that in ViewPager
you will create Fragment
s and their jobs. As we will cancel the job
in onDestroy()
during swiping in ViewPager
, we should recreate the job).
private lateinit var job: Job
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
...
job = Job()
}
创建一个协程上下文并在Fragment destroy上将其取消:
Create a coroutine context and cancel it on 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
内部.所以我用交互器重写了该代码.
In my case a problem occured when I used API requests with usual callbacks. A launch
interior inside a callback hasn't been called. So I rewrote that code with interactors.