1,初认suspend

suspend 用于暂停执行当前协程,并保存所有局部变量,被标记为 suspend 的函数只能运行在协程或者其他 suspend 函数。

首先我们看一下在retrofit 不是使用suspend关键字会造成什么错误?

IllegalArgumentException: Unable to create call adapter for
com.qxf.sample.network.BaseResponse

没有添加suspend关键字的时候回调数据不能创建返回的数据类型,类型错误了

添加上了suspend关键字,运行时会被编译成一个 Continuation

@SinceKotlin("1.3")
public interface Continuation<in T> {/*** Context of the coroutine that corresponds to this continuation.*/public val context: CoroutineContext/*** 恢复协程的调用,将成功或者失败的结果回调出去*/public fun resumeWith(result: Result<T>)
}

也可以认为是回调,这样比较直观一些;

2,使用 suspend 函数无须关心线程切换

用这个函数不会阻塞当前调用的线程。这对 UI 编程是非常有用的,因为 UI 的主线程需要不断相应各种图形绘制、用户操作的请求,如果主线程上有耗时操作会让其他请求无法及时响应,造成 UI 卡顿

lifecycleScope.launch {val posts = retrofit.get<PostService>().fetchPosts();// 由于在主线程,可以拿着 posts 更新 UI
}

这相比 callback 和 RxJava 的 API 是要好很多的。这些异步的 API 最终都得依靠回调,但回调回来在哪个线程需要调用方自己搞清楚,得看这些函数里面是怎么实现的。而有了 suspend 不阻塞当前线程的约定,调用方其实无须关心这个函数内部是在哪个线程执行的。

lifecycleScope.launch(Dispatchers.Main) {foo()}

如上面这个代码块,指定这个协程块调度到主线程执行,里面调用了一个不知道哪里来的 suspend foo 方法。这个方法内部可能是耗时的 CPU 计算,可能是耗时的 IO 请求,但是我在写这个协程块的时候,其实并不需要关心这里面到底是怎么回事,运行在哪个线程。类似地,在阅读这段协程块的时候,我们可以清楚地知道眼前的这段代码会在主线程执行,suspend foo 里面的代码是一个潜在的耗时操作,具体在哪个线程执行是这个函数的实现细节,对于当前代码的逻辑是「透明」的。

但前提是这个 suspend 函数实现正确,真正做到了不阻塞当前线程。单纯地给函数加上 suspend 关键字并不会神奇地让函数变成非阻塞的,比如假设 suspend foo 里面的实现是这样的:

suspend fun foo() = BigInteger.probablePrime(1024, Random())

这个 foo 函数的实现没有遵守 suspend 的语义,是错误的。正确的做法应该修改这个 foo 函数:

suspend fun findBigPrime(): BigInteger =  withContext(Dispatchers.Default) {  BigInteger.probablePrime(4096, Random())  }

借助 withContext 我们把耗时操作从当前主线程挪到了一个默认的后台线程池,即使是用了协程,最终还是会「阻塞」某个线程,「所有的代码本质上都是阻塞式的」,这种理解可以帮助我们认识到 Android / JVM 上最终需要线程作为执行协程的载体,但忽略了阻塞和非阻塞 IO 之分,CPU 执行线程,而上面 BigInteger.probablePrime 是一个耗时的 CPU 计算,只能等待 CPU 把结果算出来,但 IO 造成的等待并不一定要阻塞 CPU,阻塞和非阻塞 IO 是有实际区别的。比如 Retrofit 虽然支持 suspend 函数(实际上也就是包装一下基于回调的 API enqueue),但是底层依赖的 OkHttp 用的是阻塞的方法,最终执行请求还是调度到线程池里面去.

把协程和 suspend 单纯看成线程切换工具有很大的局限性。由于 suspend 就是回调,也提供了包装回调 API 的方法,基于回调的 API 都可以用 suspend 函数进行封装改造.

Kotlin 中的suspend 关键字相关推荐

  1. Kotlin中的Java静态方法等效于什么?

    本文翻译自:What is the equivalent of Java static methods in Kotlin? There is no static keyword in Kotlin. ...

  2. Kotlin系列之when关键字

    今天,我们来学习一下Kotlin的when关键字. when关键字是一个有返回值的表达式,也就是它可以返回一个值.下面说说它的各种用法. when处理枚举类 在Java中我们一般使用switch来处理 ...

  3. Kotlin中的高阶函数

    博客地址sguotao.top/Kotlin-2018- 在Kotlin中,高阶函数是指将一个函数作为另一个函数的参数或者返回值.如果用f(x).g(x)用来表示两个函数,那么高阶函数可以表示为f(g ...

  4. Kotlin中协程理解与实战(一)

    Kotlin中协程理解与实战(一) 什么是协程 在Android中协程用来解决什么问题 协程是: suspend -也称为挂起或暂停,用于暂停执行当前协程,并保存所有局部变量: resume -用于让 ...

  5. python kotlin_在Python,Java和Kotlin中标记参数和重载

    python kotlin 在多种语言之间跳来跳去可以帮助您注意到不同语言的习惯用法和最佳做法之间的某些差异. 比较有趣的差异之一与一个函数执行多项操作有关. Python 我们先来看一下Python ...

  6. 在Python,Java和Kotlin中标记参数和重载

    在多种语言之间跳来跳去可以帮助您注意到不同语言的习惯用法和最佳做法之间的某些差异. 比较有趣的差异之一与一个函数执行多项操作有关. Python 我们先来看一下Python. Python实际上无法重 ...

  7. 教你如何完全解析Kotlin中的注解

    简述: 从这篇文章将继续开始探索Kotlin中的一些高级的内容,之前有着重探讨了Kotlin的泛型以及泛型型变等内容.现在我们一起来看下Kotlin中的注解.Kotlin中的注解是100%与Java注 ...

  8. [译]Object的局限性——Kotlin中的带参单例模式

    原文:Kotlin singletons with argument --object has its limits 作者:Christophe Beyls 译者:却把清梅嗅 在Kotlin中,单例模 ...

  9. kotlin中的异常处理_Kotlin异常处理

    kotlin中的异常处理 In this tutorial, we'll be discussing Exception Handling in Kotlin. 在本教程中,我们将讨论Kotlin中的 ...

最新文章

  1. css你所不知道技巧
  2. Spark常用函数讲解之键值RDD转换
  3. RedHat_Linux环境下防火墙配置初级入门
  4. 基于无线传感器网络LEACH算法的改进
  5. pdfFactory 7PDF 虚拟打印机官方注册码版下载
  6. 简述对CAN协议栈的理解
  7. 各大主流编程语言性能PK,结果出乎意料
  8. 动态规划基础之挖金矿问题
  9. hibernate 数据分页显示 及 分页导航栏的设置
  10. 腾讯微博qq说说备份导出工具_软件推荐Day51 其他工具类 腾讯微博备份
  11. 我用nodejs给朋友发了一份邮件
  12. docker(七)容器与外部通信
  13. 宇视网络视频录像机国标对接配置指导
  14. python画热力分布图 pil_Python画attention map与原图叠加的热力图
  15. 我的艰辛作业之旅之程序设计思维week3作业
  16. 购物中心户外广场美陈设计方案
  17. 通过正则表达式快速获取电影的下载地址!正则-永远滴神!
  18. Java程序员毕业N年系列----毕业一年
  19. win7优化大师_Win7设置某个用户自动登录的方法
  20. 数据比较器,对比数据前后变化细节

热门文章

  1. js 获取如何鼠标滑词?
  2. 留学生该如何准备快消行业秋招笔试?(宝洁、联合利华、达能、强生等
  3. 9.21 Day57---搭建TM架构服务器
  4. 什么是分布式系统(通俗易懂)
  5. 从一年学舞蹈想到架构师成长
  6. U3D Image Effects实践(1)——去除红色通道
  7. 计算机一级模拟7试题,2016年9月计算机一级MSOffice考前模拟试题及答案(7)
  8. 蓝牙GATT协议介绍
  9. 本人32岁,转行做运维经验分享
  10. linux realvnc教程,RealVNC使用教程 远程控制软件RealVNC使用攻略