协程,kotlin中一个神奇的组件,由于使用方便任意切换被广大开发者使用,今天就来看看协程:
- 说说你对协程的理解
- 说下协程具体的使用
- 协程怎么取消
说说你对协程的理解
在我看来,协程和线程一样都是用来解决并发任务(异步任务)
的方案。所以协程和线程是属于一个层级的概念,但是对于kotlin
中的协程,又与广义的协程有所不同。kotlin中的协程其实是对线程的一种封装
,或者说是一种线程框架,为了让异步任务更好更方便使用。
说下协程具体的使用
比如在一个异步任务需要回调到主线程的情况,普通线程需要通过handler
切换线程然后进行UI更新等,一旦多个任务需要顺序调用
,那更是很不方便,比如以下情况:
//客户端顺序进行三次网络异步请求,并用最终结果更新UI thread{ iotask1(parameter) { value1 -> iotask1(value1) { value2 -> iotask1(value2) { value3 -> runOnUiThread{ updateUI(value3) } } } } }
简直是魔鬼调用
,如果不止3次,而是5次,6次,那还得了。。
而用协程就能很好解决这个问题:
//并发请求 GlobalScope.launch(Dispatchers.Main) { //三次请求并发进行 val value1 = async { request1(parameter1) } val value2 = async { request2(parameter2) } val value3 = async { request3(parameter3) } //所有结果全部返回后更新UI updateUI(value1.await(), value2.await(), value3.await()) } //切换到io线程 suspend fun request1(parameter : Parameter){withContext(Dispatcher.IO){}} suspend fun request2(parameter : Parameter){withContext(Dispatcher.IO){}} suspend fun request3(parameter : Parameter){withContext(Dispatcher.IO){}}
就像是同一个线程中顺序执行的效果一样,再比如我要按顺序执行一次异步任务,然后完成后更新UI,一共三个异步任务。如果正常写应该怎么写?
thread{ iotask1() { value1 -> runOnUiThread{ updateUI1(value1) iotask2() { value2 -> runOnUiThread{ updateUI2(value2) iotask3() { value3 -> runOnUiThread{ updateUI3(value3) } } } } } } }
晕了晕了,不就是一次异步任务,一次UI更新吗。怎么这么麻烦,来,用协程看看怎么写:
GlobalScope.launch (Dispatchers.Main) { ioTask1() ioTask1() ioTask1() updateUI1() updateUI2() updateUI3() } suspend fun ioTask1(){ withContext(Dispatchers.IO){} } suspend fun ioTask2(){ withContext(Dispatchers.IO){} } suspend fun ioTask3(){ withContext(Dispatchers.IO){} } fun updateUI1(){ } fun updateUI2(){ } fun updateUI3(){ }
协程怎么取消
- 取消
协程作用域
将取消它的所有子协程。
// 协程作用域 scope val job1 = scope.launch { … } val job2 = scope.launch { … } scope.cancel()
- 取消
子协程
// 协程作用域 scope val job1 = scope.launch { … } val job2 = scope.launch { … } job1.cancel()
但是调用了cancel
并不代表协程内的工作会马上停止,他并不会组织代码运行。比如上述的job1
,正常情况处于active
状态,调用了cancel
方法后,协程会变成Cancelling
状态,工作完成之后会变成Cancelled
状态,所以可以通过判断协程的状态来停止工作。
Jetpack 中定义的协程作用域(viewModelScope 和 lifecycleScope)
可以帮助你自动取消任务,下次再详细说明,其他情况就需要自行进行绑定和取消了。