前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >协程三问—快手真题

协程三问—快手真题

作者头像
码上积木
发布2020-10-29 16:40:26
4560
发布2020-10-29 16:40:26
举报
文章被收录于专栏:码上积木

协程,kotlin中一个神奇的组件,由于使用方便任意切换被广大开发者使用,今天就来看看协程:

  • 说说你对协程的理解
  • 说下协程具体的使用
  • 协程怎么取消

说说你对协程的理解

在我看来,协程和线程一样都是用来解决并发任务(异步任务)的方案。所以协程和线程是属于一个层级的概念,但是对于kotlin中的协程,又与广义的协程有所不同。kotlin中的协程其实是对线程的一种封装,或者说是一种线程框架,为了让异步任务更好更方便使用。

说下协程具体的使用

比如在一个异步任务需要回调到主线程的情况,普通线程需要通过handler切换线程然后进行UI更新等,一旦多个任务需要顺序调用,那更是很不方便,比如以下情况:

代码语言:javascript
复制
//客户端顺序进行三次网络异步请求,并用最终结果更新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(){
    }

协程怎么取消

  • 取消协程作用域将取消它的所有子协程。
代码语言:javascript
复制
// 协程作用域 scope
val job1 = scope.launch { … }
val job2 = scope.launch { … }
scope.cancel()
  • 取消子协程
代码语言:javascript
复制
// 协程作用域 scope
val job1 = scope.launch { … }
val job2 = scope.launch { … }
job1.cancel()

但是调用了cancel并不代表协程内的工作会马上停止,他并不会组织代码运行。比如上述的job1,正常情况处于active状态,调用了cancel方法后,协程会变成Cancelling状态,工作完成之后会变成Cancelled 状态,所以可以通过判断协程的状态来停止工作。

Jetpack 中定义的协程作用域(viewModelScope 和 lifecycleScope)可以帮助你自动取消任务,下次再详细说明,其他情况就需要自行进行绑定和取消了。


Android开发者们,快来关注公| 众 |号【码上积木】,每天三问面试题,并详细剖析,助你成为offer收割机。 积累也是一种力量。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-10-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码上积木 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 说说你对协程的理解
  • 说下协程具体的使用
  • 协程怎么取消
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档