当前位置: 首页 > 编程日记 > 正文

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

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了,我对它是十分看好的。

关注我的公众号

相关文章:

数据可视化相关网站

D3 gallery Gallery / D3 / Observable Flowing Data / NYTimes / … FlowingData | Data Visualization and Statistics Data Video Explorer Data Video Explorer 配色网站 配色网站 Material Design Color, Flat Colors, Icons, Color Palette | Material UI Colo…

【2012天津区域赛】部分题解 hdu4431—4441

1001&#xff1a; 题意&#xff1a;给你13张麻将牌&#xff0c;问可以胡哪些张 思路&#xff1a; 枚举可能接到的牌&#xff0c;然后dfs判断能否胡 1002&#xff1a; 题意&#xff1a; 已知n&#xff0c;m 求 n的所有约数在m进制下的平方和 做法&#xff1a;队长用java高精度写…

彻底理解OkHttp - OkHttp 源码解析及OkHttp的设计思想

OkHttp 现在统治了Android的网络请求领域&#xff0c;最常用的框架是&#xff1a;Retrofitokhttp。OkHttp的实现原理和设计思想是必须要了解的&#xff0c;读懂和理解流行的框架也是程序员进阶的必经之路&#xff0c;代码和语言只是工具&#xff0c;重要的是思想。 在OKhttp 源…

访问 Microsoft SQL Server 元数据的三种

上海微创软件有限公司 肖桂东适用读者&#xff1a;Microsoft SQL Server 中、高级用户元数据简介元数据 (metadata) 最常见的定义为"有关数据的结构数据"&#xff0c;或者再简单一点就是"关于数据的信息"&#xff0c;日常生活中的图例、图书馆目录卡和名片…

apply()智用:需要几个参数但只有一个参数数组

比奇堡的居民海绵宝宝&#xff0c;派大星&#xff0c;蟹老板正在开party let arr [SpongeBob,Patrick,Mr.Crab]; 如果章鱼哥来了&#xff0c;珊迪也来了 arr.push(Squidward Tentacles,Sandy); 此时一共派对有5人 如果章鱼哥和珊迪一起来了 arr.push.apply(arr,[Squidwar…

HTML转WORD WORD转PDF--来源网络

从网上找的代码&#xff0c;先收藏下。 功能&#xff1a;实现HTML转WORD&#xff0c;WORD转PDF view source print?using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using Syst…

正则表达式小结

基础 数量匹配 *代表{0,} 代表{1,} ?代表{0,1} [0-9][0-9]{1,} 表示匹配0~9中的任意数字&#xff0c;并且至少1位。 [0-9]*[0-9]{0,} 表示匹配0~9中的任意数字&#xff0c;并且可以是0位&#xff08;不存在&#xff09;。 [0-9]?[0-9]{0,1} 表示匹配0~9中的任意数字&…

Log控制台打印设置

android Log.isLoggable方法的使用 android 动态控制logcat日志开关,通过Log.isLoggable&#xff08;TAG,level&#xff09;方法动态控制&#xff0c;1.添加日志的时候加入判断&#xff0c; String TAG"Volley"; boolean isDbugLog.isLoggable(TAG, Lo…

JavaScript 定义类时如何将方法提取出来

现在我们有一个海洋生物类 function marineLife(name,job,friend){this.name name;this.job job;this.friend friend;this.introduceMyself function(){console.log(大家好&#xff01;我叫this.name,我是一名this.job,我最好的朋友是this.friend);} } 让我们用这个类新建…

错误:Error #2032解决方案

问题&#xff1a; Error #2032错误要访问外部数据&#xff0c;必须信任此文件。 现象&#xff1a; 要访问外部数据&#xff0c;必须信任此文件。 对于 PDF 文件&#xff0c;在 Adobe Reader 中&#xff0c;单击“Edit”&#xff08;编辑&#xff09;>“Preferences”&#…

[转]c# 泛类型(泛型) 以及强类型与弱类型的 理解及优化

[泛型的概念]&#xff08;1&#xff09;没有泛型的时候&#xff0c;所有的对象都是以object为基础&#xff0c;如果要使用时必须进行强制类型转换&#xff0c;如果对于值类型&#xff0c;则会导致不断拆箱装箱的过程&#xff0c;对系统消耗很大。&#xff08;2&#xff09;使用…

docker宿主机访问docker容器服务失败

2019独角兽企业重金招聘Python工程师标准>>> 原因&#xff1a; 因为docker的虚拟ip网段是172.17.*。*与局域网的ip网段172.17冲突了&#xff0c;所以有两种方式&#xff1a; 解决方法&#xff1a; 一、 修改docker网卡信息&#xff0c;将网段改为与局域网不同的即可…

从变量地址到指针再到指针变量

标题中的3个概念&#xff1a;变量地址、指针and指针变量是依次出现的&#xff0c;逐个确定就可以明晰到底什么是我们常说的指针(其实是指针变量) 首先&#xff0c;变量在本质上是一段存储空间&#xff0c;既然是存储空间&#xff0c;就必有地址&#xff0c;一般每个字节有一个…

Lua bind 和 conf 实现

Lua &#xff0c;语法简单&#xff08;极像javascript), 移植性好(纯C实现), 启动速度快&#xff0c;空间占用小&#xff0c; 真不愧是潜入式脚本语言之王。 本人想拿它来做 配置文件(conf)&#xff0c;也想加一点IoC, 就是配置脚本可以调用主程序的函数。 实现如下&#xff1…

通过反射执行get、set方法

Class clazz sourceObj.getClass(); 1、获取所有属性 BeanInfo beanInfo Introspector.getBeanInfo(clazz); PropertyDescriptor[] pds beanInfo.getPropertyDescriptors(); 2、获取指定属性 PropertyDescriptor pd new PropertyDescriptor(fieldName, clazz); Method getM…

h5 移动端 关于监测切换程序到后台或息屏事件和visibilitychange的使用

需求&#xff1a;当我们页面上正在播放视频或者播放背景音乐时&#xff0c;我们屏幕自动息屏或者切换程序去看消息时&#xff0c;我们希望暂停视频或背景音乐&#xff0c;回到程序我们希望继续播放视频或播放背景音乐。小程序上提供了 onUnload返回 onHide退出 onShow重新进入等…

一份整理 | PyTorch是什么,为何选择它

PyTorch是什么 PyTorch的特性 PyTorch是什么 PyTorch是一个基于Python的科学计算包&#xff0c;主要提供以下两种用途&#xff1a; 在GPU算力或其他加速器上作为NumPy的替代一个用于实现神经网络的自动求导库 PyTorch的特性 PyTorch的祖先是Chainer,HIPS autograd,twitter…

jquery实现心算练习

看看大家做完要多长时间&#xff0c;不能上传附近&#xff0c;就只得贴代码。代码如下&#xff1a; 代码 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">2 <htm…

C/C++利用三元组实现稀疏矩阵运算

三元组&#xff08;&#xff08;x&#xff0c;y&#xff09;&#xff0c;z&#xff09;其中&#xff08;x&#xff0c;y&#xff09;表示非零元位置&#xff0c;z表示该坐标的值 由于实际操作时&#xff0c;我们所用的矩阵0非常多&#xff0c;所以一个一个输入值很浪费时间&…

Database项目中关于Procedure sp_refreshsqlmodule_internal的错误

最近项目中发现一怪问题&#xff0c;使用DB项目发布数据库时&#xff0c;总提示 “(110,1): SQL72014: .Net SqlClient Data Provider: Msg 1222, Level 16, State 56, Procedure sp_refreshsqlmodule_internal, Line 67 Lock request time out period exceeded. An error occu…

脱离公式谈谈对反向传播算法的理解

机器学习的训练过程可看作是最优化问题的求解过程。 根据原理 对于函数f(x),如果f(x)在点xt附近是连续可微的&#xff0c;那么f(x)下降最快的方向是f(x)在xt点的梯度的反方向 得到最简单最常用的优化算法&#xff1a;梯度下降法(Gradient Descent Method)。 可以想见&#xf…

如何在Form中使用键弹性域(Key Flexfield)

在应用弹性域之前必须先定义弹性域&#xff0c;定义之前必须先注册表列。如果你的弹性域已经在Oracle Application Object Library中已经定义和注册了&#xff0c;并且弹性域表和列已经在数据库中存在&#xff0c;则忽略1、2、3步骤&#xff0c;适用于关键性也适用于描述性弹性…

什么是SOLID原则(第3部分)

让我们从最后一个 SOLID 原则开始吧&#xff0c;即依赖倒置原则&#xff08;Dependency Inversion Principle&#xff0c;简称 DIP&#xff09;&#xff08;不要和依赖注入Dependency Injection &#xff0c;DI 弄混淆了&#xff09;。这个原则所说的是高级模块不应该依赖具象的…

李彦宏,韩寒等入围本年度《时代百人》候选名单

美国《时代》杂志周六&#xff08;4月3日&#xff09;公布了2010年度 “百位全球最具影响力人物”的200名候选人名单,其中中国最大网络搜索公司“百度”总裁李彦宏也以成功企业家入围候选人,同时入围的还有年仅27岁的80后作家韩寒。 其它“全球最具影响力人物”候选人名单中还包…

win10如何查看NVIDIA驱动的版本

入口 输入&#xff1a;控制面板 选择&#xff1a;硬件和声音 选择NVIDIA控制面板 点击小房子图标 看到版本是391.25

vb中5种打开文件夹浏览框的方法总结(转)

代码 众所周知&#xff0c;在vb中如果是打开某一个文件的话&#xff0c;非常简单&#xff0c;使用CommonDialog组件即可轻松完成&#xff0c;但是他只能选择文件&#xff0c;之后或许选取的文件路径&#xff0c;而如果想要浏览文件夹&#xff0c;就没这么方便了。这里介绍3个办…

R语言文摘:Subsetting Data

原文地址&#xff1a;https://www.statmethods.net/management/subset.html R has powerful indexing features for accessing object elements. These features can be used to select and exclude variables and observations. The following code snippets demonstrate ways…

Ubuntu系统

1. Ubuntu 14.04 LTS安装 直接从官网下载Ubuntu14.04.2LTS http://www.ubuntu.com/download/desktop (你也可以下载最新的14.10---据说改变不大) 个人采用的是U盘安装,用了UltraISO这款软件(百度软件中心中便有---可以不破解试用来完成目的):具体流程: UltraISO上端文件打开,将…

win10下Anaconda如何查看PyTorch版本

以管理员身份打开Anaconda Powershell Prompt 按顺序输入以下三行命令即可

6年iOS开发程序员总结组件化—让你的项目一步到位

纯个人学习笔记分享, 不喜勿喷,自行取关! 技术不缺乏缔造者,网络不缺乏键盘侠,但缺乏分享技术的源动力! 近几年组件化大家吵的沸沸扬扬的&#xff0c;它其实也不是什么黄金圣衣&#xff0c;穿上立马让你的小宇宙提升几个档次&#xff0c;也不是海皇的三叉戟&#xff0c;入手就能…