use*_*087 4 android kotlin kotlin-coroutines
abstract class ScopedAppActivity: AppCompatActivity(), CoroutineScope {
protected lateinit var job: Job
override val coroutineContext: CoroutineContext
get() = job + Dispatchers.Main
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
job = Job()
launch(Dispatchers.Main) {
try {
delay(Long.MAX_VALUE)
} catch (e: Exception) {
// e will be a JobCancellationException if the activty is destroyed
}
}
}
override fun onDestroy() {
super.onDestroy()
job.cancel()
}
}
Run Code Online (Sandbox Code Playgroud)
这个例子是从协程指南中复制的,并由launch(Dispatchers.Main)
协程扩展。我不明白为什么+ Dispatchers.Main
需要第 4 行。如果我删除这部分,launch
如果 Activity 被销毁,协程无论如何都会被取消。那么是什么原因Dispatchers.Main
呢?为什么也Dispatchers.IO
没有添加?
当你写这个:
launch(Dispatchers.Main) {
try {
delay(Long.MAX_VALUE)
} catch (e: Exception) {
// e will be a JobCancellationException if the activty is destroyed
}
}
Run Code Online (Sandbox Code Playgroud)
您可能没有意识到launch
实际上是以您的ScopedAppActivity
身份调用的。所以你有效地写了
this.launch(Dispatchers.Main) { ... }
Run Code Online (Sandbox Code Playgroud)
launch
是一个扩展函数CoroutineScope
,它将使用它coroutineContext
作为起点,将它与您在括号中指定的任何内容结合起来。所以,在你的情况下,有效的上下文是
job + Dispatchers.Main + Dispatchers.Main
Run Code Online (Sandbox Code Playgroud)
可以想象,这等于
job + Dispatchers.Main
Run Code Online (Sandbox Code Playgroud)
所以当你Dispatchers.Main
从你的 中删除时coroutineContext
,没有任何变化。
那么 Dispatchers.Main 的原因是什么?
提供Dispatchers.Main
in的好处coroutineContext
是你不必每次都提供它,所以你可以直接写
launch { ... }
Run Code Online (Sandbox Code Playgroud)
并且里面的块launch
将停留在 GUI 线程上,这是在 Android 和其他 GUI 应用程序上使用协程最自然的方式。
为什么也没有添加 Dispatchers.IO?
由于该行不是关于声明您将使用的所有调度程序,而是默认调度程序,因此提供多个调度程序是没有意义的。
在另一个层面上,CoroutineContext
它不是一个列表(这是+
运算符隐含的),而是一个映射。该+
语法有效,因为您添加的每个对象都声明了自己的映射键,+
用于将其放入上下文的内部映射中。所以实际上不可能将两个调度器合二为一CoroutineContext
。
归档时间: |
|
查看次数: |
1957 次 |
最近记录: |