协程三问—快手真题

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

协程,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)可以帮助你自动取消任务,下次再详细说明,其他情况就需要自行进行绑定和取消了。

目录
相关文章
|
小程序 API
小程序踩坑记- tabBar.list[3].selectedIconPath 大小超过 40kb
小程序踩坑记- tabBar.list[3].selectedIconPath 大小超过 40kb
345 0
|
Linux 虚拟化 Docker
|
存储 监控 容灾
关系型数据库的单点故障风险
【5月更文挑战第3天】关系型数据库的单点故障风险
268 6
关系型数据库的单点故障风险
|
XML 设计模式 Java
PowerMock的静态方法与私有方法怎么测试?
**PowerMock**是Java单元测试中的增强工具,扩展了Mockito,支持模拟静态方法、构造函数、私有方法和final类,促进更高测试覆盖率。它用于隔离依赖,测试静态方法和私有方法。常见问题包括配置复杂性、过度使用、忽略真实行为模拟和最佳实践。解决方案包括遵循官方文档、谨慎使用、精确模拟和测试后清理。示例展示了如何模拟静态方法,通过添加PowerMock依赖和使用`@RunWith(PowerMockRunner.class)`、`@PrepareForTest`注解,以及`PowerMockito.mockStatic()`进行静态方法模拟。
404 0
|
11月前
|
Java 编译器 Maven
Java“class file contains wrong class”解决
当Java程序运行时出现“class file contains wrong class”错误,通常是因为类文件与预期的类名不匹配。解决方法包括:1. 确保类名和文件名一致;2. 清理并重新编译项目;3. 检查包声明是否正确。
311 3
|
Java 应用服务中间件 Go
证书格式有哪些,区别以及如何生成证书
证书格式有哪些,区别以及如何生成证书
669 4
|
编解码 算法 BI
增强型植被指数EVI、ndvi数据、NPP数据、GPP数据、土地利用数据、植被类型数据、降雨量数据
增强型植被指数EVI、ndvi数据、NPP数据、GPP数据、土地利用数据、植被类型数据、降雨量数据
增强型植被指数EVI、ndvi数据、NPP数据、GPP数据、土地利用数据、植被类型数据、降雨量数据
|
SQL 关系型数据库 MySQL
事务隔离大揭秘:MySQL中的四种隔离级别解析
事务隔离大揭秘:MySQL中的四种隔离级别解析
3240 0
|
人工智能 网络协议 应用服务中间件
Hexo博客SSL证书到期,该如何免费续期更换?
Hexo博客SSL证书到期,该如何免费续期更换?
|
存储 异构计算