不记得Rxjava吧,你应该试试Kotlin的协程

作者 : 开心源码 本文共3265个字,预计阅读时间需要9分钟 发布时间: 2022-05-12 共174人阅读

0.前言

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

1.什么是协程

1.1协程定义

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

[图片上传失败…(image-28737d-1545213507440)]

看这个图,协程就是这样,在一个线程中顺序执行的,先执行一段程序,这里用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"?><FrameLayout        xmlns: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">    <TextView            android:id="@+id/timeTV"            android:layout_width="wrap_content"            android:layout_height="wrap_content"/>    <Button            android:id="@+id/sendBT"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="SEND"            android:layout_gravity="center"/>    <ProgressBar            android: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.VISIBLE            val 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了,我对它是十分看好的。

image

关注我的公众号

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » 不记得Rxjava吧,你应该试试Kotlin的协程

发表回复