最简单的使用
1
2
3
GlobalScope.launch(Dispatchers.IO) {
...
}
什么是协程
- 在程序中处理并发任务的方案,也是这种方案的一个组件。
- 协程和线程属于同一个层级的概念。
- 协程中不存在线程,也不存在并行。
并发
1
2
3
4
5
GlobalScope.launch(Dispatchers.Main) {
val result1 = async { ... }
val result2 = async { ... }
textView.text = "${result1.await()} - ${result2.await()}"
}
协程泄漏
和新开线程类似,在 Activity 销毁的时候,正在执行的协程不会停止而导致异常问题。
-
手动取消某个协程
1 2
val job = GlobalScope.launch { } job.cancel()
-
通过 Scope 管理协程
1 2 3 4
val scope = MainScope() scope.launch { ... } scope.launch { ... } scope.cancel() // 取消所有使用 scope 的协程
-
协程被取消后,任务并没有中止
-
在协程任务中判断当前协程是否被取消:
1 2 3 4 5 6
GlobalScope.launch { var i = 0 while (i < 5 && isActive) { // isActive 判断当前协程是否被取消 println("say hello $i times") } }
-
使用默认的检查器:
1 2 3 4 5 6 7
GlobalScope.launch { var i = 0 while (i < 5) { ensureActive() // 如果当前协程处于 cancel 状态,则直接抛 CancellationException println("say hello $i times") } }
-
在 Architecture components 中使用协程
-
ViewModelScope
-
LifecycleScope
1 2 3 4
lifecycleScope.launch { ... } lifecycleScope.launchWhenCreated { ... } lifecycleScope.launchWhenStarted { ... } lifecycleScope.launchWhenResumed { ... }
并且不用在 onDestory 中执行
lifecycleScope.cancel()
,因为这会被自动执行。
其他
- 关于并发和并行:来源知乎
- 你吃饭吃到一半,电话来了,你一直到吃完了以后才去接,这就说明你不支持并发也不支持并行。
- 你吃饭吃到一半,电话来了,你停了下来接了电话,接完后继续吃饭,这说明你支持并发。
- 你吃饭吃到一半,电话来了,你一边打电话一边吃饭,这说明你支持并行。
- 事件流 Flow