协程,kotlin中一个神奇的组件,由于使用方便任意切换被广大开发者使用,今天就来看看协程:
- 说说你对协程的理解
- 说下协程具体的使用
- 协程怎么取消
说说你对协程的理解
在我看来,协程和线程一样都是用来解决并发任务(异步任务)
的方案。所以协程和线程是属于一个层级的概念,但是对于kotlin
中的协程,又与广义的协程有所不同。kotlin中的协程其实是对线程的一种封装
,或者说是一种线程框架,为了让异步任务更好更方便使用。
说下协程具体的使用
比如在一个异步任务需要回调到主线程的情况,普通线程需要通过handler
切换线程然后进行UI更新等,一旦多个任务需要顺序调用
,那更是很不方便,比如以下情况:
//客户端顺序进行三次网络异步请求,并用最终结果更新UI
thread{
iotask1(parameter) { value1 ->
iotask1(value1) { value2 ->
iotask1(value2) { value3 ->
runOnUiThread{
updateUI(value3)
}
}
}
}
}
简直是魔鬼调用
,如果不止3次,而是5次,6次,那还得了。。
而用协程就能很好解决这个问题:
代码语言:javascript复制//并发请求
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,一共三个异步任务。如果正常写应该怎么写?
代码语言:javascript复制thread{
iotask1() { value1 ->
runOnUiThread{
updateUI1(value1)
iotask2() { value2 ->
runOnUiThread{
updateUI2(value2)
iotask3() { value3 ->
runOnUiThread{
updateUI3(value3)
}
}
}
}
}
}
}
晕了晕了,不就是一次异步任务,一次UI更新吗。怎么这么麻烦,来,用协程看看怎么写:
代码语言:javascript复制 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)
可以帮助你自动取消任务,下次再详细说明,其他情况就需要自行进行绑定和取消了。
Android开发者们,快来关注公| 众 |号【码上积木】,每天三问面试题,并详细剖析,助你成为offer收割机。 积累也是一种力量。