0.前言

协程以前一直是Kotlin作为实验性的一个库,前些日子发现1.3版本的kotlin relese了协程,所以就找时间研究了一下,本来早就想写这篇文章了,但是因为离职换工作的原因,迟迟未能动笔,这两天终于算搞完了,记录一下我对协程的一些理解。

1.什么是协程

1.1协程定义

我第一次接触协程是在python的教程里,当时廖雪峰在其中的解释还是不错的,这里拿来用来解释一下:子程序,或者称为函数,在所有语言中都是层级调用,比如A调用B,B在执行过程中又调用了C,C执行完毕返回,B执行完毕返回,最后是A执行完毕。所以子程序调用是通过栈实现的,一个线程就是执行一个子程序。子程序调用总是一个入口,一次返回,调用顺序是明确的。而协程的调用和子程序不同。协程看上去也是子程序,但执行过程中,在子程序内部可中断,然后转而执行别的子程序,在适当的时候再返回来接着执行。注意,在一个子程序中中断,去执行其他子程序,不是函数调用,有点类似CPU的中断。

看这个图,协程就是这样,在一个线程中顺序执行的,先执行一段程序,这里用continuation表示,然后遇到suspension point是,程序悬挂,进行下一个continuation子程序的运行。

1.2协程和线程的关系

协程和线程,都能用来实现异步调用,但是这两者之间是有本质区别的

(1)协程是编译器级别的,线程是系统级别的。协程的切换是由程序来控制的,线程的切换是由操作系统来控制的。

(2)协程是协作式的,线程是抢占式的。协程是由程序来控制什么时候进行切换的,而线程是有操作系统来决定线程之间的切换的。

(3)一个线程可以包含多个协程。

(4)Java中,多线程可以充分利用多核cpu,协程是在一个线程中执行。

(5)协程适合io密集型的程序,多线程适合计算密集型的程序(适用于多核cpu的情况)。当你的程序大部分是文件读写操作或者网络请求操作的时候,这时你应该首选协程而不是多线程,首先这些操作大部分不是利用cpu进行计算而是等待数据的读写,其次因为协程执行效率较高,子程序切换不是线程切换,是由程序自身控制,因此,没有线程切换的开销,和多线程比,线程数量越多,协程的性能优势就越明显。 (6)使用协程可以顺序调用异步代码,避免回调地狱。

2.简单用法

这里我打算模仿一个网络请求,点击button发送网络请求,显示一个progressbar打转,返回结果后一个textview显示结果并隐藏progressbar 先看一下布局文件

<?xml version="1.0" encoding="utf-8"?>
<FrameLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><TextViewandroid:id="@+id/timeTV"android:layout_width="wrap_content"android:layout_height="wrap_content"/><Buttonandroid:id="@+id/sendBT"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="SEND"android:layout_gravity="center"/><ProgressBarandroid:layout_gravity="center"android:visibility="gone"android:id="@+id/loadingPB"android:layout_width="wrap_content"android:layout_height="wrap_content"/></FrameLayout>
复制代码

一个Button,一个TextView,一个ProgressBar

class MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)sendBT.setOnClickListener {coroutineSend()}}private fun coroutineSend() {val uiScope = CoroutineScope(Dispatchers.Main)uiScope.launch {loadingPB.visibility = View.VISIBLEval deffer = async(Dispatchers.Default) {getCoroutineResult()}val coroutineResult = deffer.await()timeTV.text = "get $coroutineResult"loadingPB.visibility = View.GONE}}private suspend fun getCoroutineResult(): String {delay(9000L)return "coroutine result"}
}复制代码

首先创建了一个CoroutineScope,所有协程都运行在CoroutineScope中,创建CoroutineScop中传入参数Dispatchers.Main,这是一个协程调度器,它确定了相应的协程在执行时使用一个或多个线程。协程调度器可以将协程的执行局限在指定的线程中,调度它运行在线程池中或让它不受限的运行。 调用launch,就启动了一个协程,launch方法会返回一个job,调用cancel方法可以取消这个协程的进行。可以看到在协程里我们先展示出loadingPB,然后调用async又启动一个协程,同时使用Dispatchers.Default这个协程调度器,它将使协程在执行时使用一个DefaultDispatcher-worker-1线程,这里为什么使用async而没有使用launch,是因为async会返回一个Deferred对象,调用其await方法可以阻塞执行流等到协程执行完毕返回结果,这样可以得到一个返回值,在这个async创建的协程里使用了使用了suspend方法

 private suspend fun getCoroutineResult(): String {delay(9000L)return "coroutine result"}
复制代码

先休眠9秒钟,然后返回一个字符串,注意这里这个delay也是suspend方法,一个suspend方法只能在协程或者suspend方法里调用。关于协程还有一些其他的创建和使用方法,有兴趣的可以去看看官方教程。

3.Rxjava VS 协程

协程相对RxJava有什么优点呢?

(1)RxJava堆栈可读性查,一旦出现问题,堆栈信息爆炸,难以定位问题,而协程就可以避免这个问题

(2)协程用同步的方式写异步的代码,美好了生活,方便代码阅读。

(3)协程学习曲线比较平坦,相对于RxJava,协程对初学者更易于学习。

4.最后

这年头用Kotlin来开发android应用确实越来越爽快了,一些新的特性也逐渐加入到Kotlin中,值得更加学习,当然还有Flutter,以后会陆续写几个关于Flutter的文章,毕竟release了,我对它是十分看好的。

关注我的公众号

忘记Rxjava吧,你应该试试Kotlin的协程相关推荐

  1. Kotlin高级协程

    Kotlin高级协程 一.前言 二.先从线程说起 三.协程的设计思想 四.协程特点:优雅的实现移步任务 五.协程基本使用 六.协程和线程相比有什么特点,如何优雅的实现异步任务 一.前言 在文章正式上干 ...

  2. 【对比Java学Kotlin】协程简史

    文章目录 一.概念释义 1.1 协程定义 1.2 与线程的关系 1.3 协程简史 二.种类划分 2.1 按调用栈分类 2.2 按调度方式分类 三.异步编程 3.1 多线程 3.2 回调 3.3 Pro ...

  3. 十一、kotlin的协程 - 缓存、volatile、内存屏障和cas(四) --- 跑题篇

    本章写着写着就跑题了, 又不舍得删除, 新手看 # 协程的共享变量安全问题简单入门和## volatile 不保证原子性部分代码, 其他可以不看, 太乱, 也没用 协程的共享变量安全问题简单入门 在使 ...

  4. Kotlin的协程与生命周期

    文章目录 一.前言 二.引入依赖 三.代码示例 1.基础用法 2.repeatOnLifecycle 3.flowWithLifecycle 4.lifecycle.whenCreated.lifec ...

  5. 十一、kotlin的协程(一)

    theme: Chinese-red 学习的前提 java线程需要大概知道点 协程是线程执行的任务, 协程和用户线程的区别在于, 协程背靠强大的编译器, 协程有专属于协程的调度器和一堆方便好用的函数, ...

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

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

  7. Kotlin(3)-协程和操作符重载,Java程序员秋招三面蚂蚁金服

    Kotlin 文件和类不存在一对一关系 共生体 继承 修饰符 空指针问题 正文 重难点 协程 想了很久,关于协程的内容,在官网上确实有很多内容,基础知识概念,基本使用,以及 流操作,通道,异常处理,并 ...

  8. kotlin coroutines 协程教程-入门用法

    kotlin coroutines 协程教程-入门用法 Coroutine 协程,是kotlin 上的一个轻量级的线程库,对比 java 的 Executor,主要有以下特点: 更轻量级的 api 实 ...

  9. Kotlin 之 协程

    初识协程,启动取消协程,Flow异步流,协程并发 目录 (一)初识协程 协程是什么? Android中协程解决了什么问题? 协程的挂起与恢复 挂起和阻塞 协程的调度器 Dispatchers 任务泄露 ...

最新文章

  1. iOS 中 OC项目使用swift第三方工具(OC、swift 混合)
  2. linux——数据库mariadb的基础操作
  3. 用配置还用Attribute来实现IoC?
  4. mybatis主键是在insert前生成还是之后生成
  5. Aloha:一个略屌的分布式任务调度框架
  6. (二)建筑物多边形化简系列——多边形点数化简
  7. jQuery Api 学习(一、jQuery 概念 和 jQuery 文档)
  8. proDAD Adobe pr cc2020 会声会影视频转场特效制作软件,滤镜特效插件
  9. cramer定理_克莱姆(cramer)法则及定理简介.ppt
  10. Python菜鸟入门: 如何在Python中读写文件
  11. 【PTA】日程安排(多重继承+重载)
  12. adb 查看屏幕大小_Android adb获取屏幕分辨率
  13. source insight4.0各种问题处理方法汇总
  14. Sqli-labs 基本注入篇 (Less1~22)
  15. C# 使用WebSocket创建聊天室案例
  16. 邮箱批量导入联系人只需3步
  17. fluentdpm模型公式_FLUENT中应用DPM模型时双R分布的详细说明
  18. 几个朋友合伙创业,如何分配股权?
  19. QGC(QGroundControl)地面站手把手教你改——高德地图的添加和瓦片地图在线资源
  20. 信息学奥赛一本通-1012:计算多项式的值

热门文章

  1. Android开发学习笔记:WebView 一
  2. 编译u-boot时候,make distclean 出现rm:无法删除,****是一个目录
  3. 非递归一次性加载分类数据到TreeViw
  4. Java泛型使用需要小心
  5. C语言中的字符串处理
  6. 20种看asp源码的方法及工具
  7. 朴素、Select、Poll和Epoll网络编程模型实现和分析——模型比较
  8. 64位Ubuntu上编译32位程序操作步骤
  9. avue validate 变为不可编辑_排版技巧——如何用 Word 编辑参考文献
  10. win7能用的matlab,win7环境下使用matlab7.0(R14)方法