Kotlin Coroutine(协程): 一、样例

全面认识Kotlin协程(Coroutine/Channel/Flow) 全面认识Kotlin协程: Coroutine/Channel/Flow,协程是协作式任务, 线程是抢占式任务, 本质上两者都属于并发。 阅读详情


前言

你还在用 Hanlder + Message? 或者 AsyncTask? 你还在用 Rxjava?
有人说Rxjava和Coroutine是从不同维度解决异步, 并且Rxjava的强大不止于异步问题.
好吧, 管它呢. 让我们拥抱 Coroutine(协程) 吧.

协程的篇幅有点长, 需要自己编写大量的测试例子. 从入门到都学完, 难度还是挺大的. 所以:我们直接把例子摆出来. 至于其他的, 我们从浅到深,日后..日后..再说 [奸笑]

没有描述


Kotlin中文站: 请看官网


准备:
lifecycle 都有吧? 例子中需要用到 lifecycleScope;

//coroutines: 协程
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.3"
//coroutines for Android
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.3'

//lifecycle
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.2.0'

没有lifecycle 怎么办? 当页面销毁时,那些延时任务, 例如Handler, 网络请求 啥的, 需要及时关闭, 它们会影响 Activity 的及时销毁, 带来内存泄漏的风险. 协程也是如此.

此时我们必须自己管理协程的作用域; 所以最好还是用 lifecycleScope.

//自己定义作用域, 页面销毁时, 取消协程.  替换lifecycleScope即可;
val mainScope = MainScope()	
override fun onDestroy(){
    super.onDestroy()
    mainScope.cancel()
}

什么是协程作用域呢? 类似于生命周期, 当页面销毁时, 协程应当随之停止.


提示:以下是本篇文章正文内容,下面案例可供参考

一、直接上例子

协程能干嘛? 延时任务, 异步任务, 定时任务, 并行任务, 协程+Retrofit. 异步流? 通道?

1.延时任务.

比较常见的业务场景, 几秒钟后执行…

还记得handler怎么写吗? 定义 Handler 实现类, 然后

mHandler.sendMessageDelayed()
//或者
mHandler.postDelayed(Runnable{...})

使用协程:

doDelayed()

fun doDelayed() = lifecycleScope.launch {
    delay(2000L)	//协程挂起2秒
    binding.tvTitle.text = "变变变, 我是百变小魔女"
}
  • lifecycleScope: 默认主线程. 它会监听Activity生命周期, 不需要手动 cancel()
  • launch: 非阻塞形式启动协程.
  • delay(2000): 挂起协程, 2秒后恢复.

然后封装一下:

//执行延时任务
fun CoroutineScope.doDelayed(timeMillis: Long, block: suspend () -> Unit) = this.launch {
    delay(timeMillis)
    block.invoke()
}

//使用
lifecycleScope.doDelayed(2000L){
    binding.tvTitle.text = "变变变, 我是百变小魔女"
}

2.异步任务

在子线程执行任务, 完事回调主线程
代码如下:

doOnBack()

// 模拟子线程中执行了2秒钟的任务, 
private fun doOnBack() = lifecycleScope.launch {
    val result = withContext(Dispatchers.IO){
        delay(2000) // 假装努力干活中..
        "变变变, 我是百变小魔女"
    }
    binding.tvTitle.text = result
}

//或者. async .
private fun doOnBack() = lifecycleScope.launch {
   val deferred = async (Dispatchers.IO){
        delay(2000) // 假装努力干活中..
        "变变变, 我是百变小魔女"
    }
    binding.tvTitle.text = deferred.await()
}
  • withContext(): 不新建协程, 它只指定 执行当前代码块 所需的线程;
  • async: 创建一个协程; 它返回一个Deferred, 而lanuch返回Job对象. 多个async可以支持并发, await()是等待任务执行完毕,并返回结果.
  • Dispatchers.IO: 协程调度器. 几种调度器如下所示
参数意义
不指定它从启动了它的 CoroutineScope 中承袭了上下文
Dispatchers.Main用于Android. 在UI线程中执行
Dispatchers.IO子线程, 适合执行磁盘或网络 I/O操作
Dispatchers.Default子线程,适合 执行 cpu 密集型的工作
Dispatchers.Unconfined管它呢, 不常用, 先不管

由于异步任务需要两段代码块. 子线程代码,及主线程响应; 所以就不封装了; 并且里面其实就一句 withContext(Dispatchers.IO) 或者 val deferred = async (Dispatchers.IO)

3.并行任务:

有时多个任务异步进行, 而我们不清楚哪一个会先完成, 我们需要等待它们的最终结果时.

private suspend fun taskOne(): Int {
    delay(2000)	//模拟任务执行 2秒
    return 1
}

private suspend fun taskTwo(): Int {
    delay(1500) 	//模拟任务执行 1.5秒
    return 2
}

private suspend fun taskExecute(): Int = coroutineScope {
    val result1 = async(Dispatchers.IO) { taskOne() }
    val result2 = async(Dispatchers.IO) { taskTwo() }
    result1.await() + result2.await()
}

//使用
lifecycleScope.launch {
    val sum = taskExecute()
    binding.tvTitle.text = "变变变, 我是百变小魔女$sum"
}

taskOne 执行需要2秒; taskTwo 执行需要1.5秒; 并行, 任务总共耗费约 2秒时间.
suspend: 标志挂起函数, 挂起函数只能在协程中运行.

4.定时任务:

定时任务简单啊, delay()不阻塞线程啊.

lifecycleScope.launch {
    repeat(Int.MAX_VALUE){
        delay(1000L)
        binding.tvTitle.text = "变变变, 我是百变小魔女$it"
    }
}

这个定时任务, 每次执行, 只设置TextView的text.
我们假设我们的业务比较复杂, 每次需要耗费300ms; 如下所示:

lifecycleScope.launch {
    repeat(Int.MAX_VALUE){
        delay(1000L)
        
        //假设我们的任务比较繁重, 每次需要消耗300ms
        delay(300L)
        binding.tvTitle.text = "变变变, 我是百变小魔女$it"
    }
}

显而易见, 此时至少要 1300ms 才能循环一次. 所以上面写的1000ms只能算是间隔时间. 而任务执行需要时间, 协程挂起,恢复需要时间, 任务进入队列到线程执行也需要时间.

因此:
当定时任务的精确度要求不高, 每次执行的代码任务比较轻便. 耗时较少时, 可以用这种方式.

有的时候, 我们锁屏了, 或者跳到别的页面了, 我们不需要定时一直执行, 即便更新了UI, 我们也看不到啊! 所以,我们希望页面离开时, 定时取消. 页面显示时,重新启动定时即可:
我们就以秒杀倒计时为例;

private var endTime: Long = 0	//秒杀截止时间

//秒杀剩余 5分钟
endTime = System.currentTimeMillis() + 300 * 1000

lifecycleScope.launchWhenResumed {  //onPause 的时候会暂停.
    repeat(Int.MAX_VALUE){
        val now = System.currentTimeMillis()
        binding.tvTitle.text = if(now >= endTime){
            "秒杀结束"
        }else{
            val second = (endTime - now) / 1000 + 1
            "秒杀倒计时($second); it=$it"
        }
        delay(1000L)
    }
}

launchWhenResumed: 当页面 Resumed 时, 启动协程. onPause()时自动停止. 页面重新显示时恢复. 通过观察这里的 it, 可以断定 协程只是被挂起, 而不是销毁重建.
同样的还有: launchWhenCreated; launchWhenStarted 当然这是 lifecycle 的知识了.

有时, 我们需要精确的定时器.

可以用, java.util 包下的 Timer, 如下所示; 也可以用 CountDownTimer

val timer = timer("定时Thread_name", false, 2000, 1000){
    letUsPrintln("定时器, 这是个子线程")
}

当然, 它没有自动暂停恢复的功能; 取消执行时, 别忘了 cancel();

协程+Retrofit 的封装还是放到后面吧…


总结

没啥好总结的, 复制粘贴就完事了. 下一篇我们再深入浅出的了解协程 [奸笑]

上一篇: Room-数据持久化存储(进阶)
下一篇: Kotlin Coroutine(协程): 二、初识协程

最全面的Kotlin协程: Coroutine/Channel/Flow 以及实际应用 协程这个概念在1958年就开始出现, 比线程更早, 目前很多语言开始原生支, Java没有原生协程但是可以大型公司都自己或者使用第三方库来支持协程编程, 但是Kotlin原生支持协程. 我认为协程的核心就是一个词: 作用域, 理解什么是作用域就理解协程了 什么是协程 协程是协作式任务, 线程是抢占式任务, 本质上两者都属于并发 Kotlin协程就是线程库不是协程? 内部代码用的线程池? 最知名的协程语言Go内部也是维护了线程, 他也不是协程了? 协程只是方便开发者处理异步, 线程才能提升性能效率, 两者本 阅读详情

相关推荐

思博伦Spirent TestCenter创建单播流uni-stream

Traffic Generator列表中会出现刚才创建的uni-stream,创建完成。通常测试情况下,主要对Ethenet II和IPv4 Header进行配置。(通常情况下,如果流配置比较规范,选择任意端口接收,也没问题。编辑uni-stream基本信息。配置本条流由STC哪个端口接收。

辗转反测的博客 1681

kotlin协程

Kotlin协程是一种轻量级的并发机制,它基于线程而不是进程,使得开发者能够更加高效地管理异步任务,避免了回调地狱的问题。协程是在一种非抢占式的多任务环境中运行,它是一种将并发代码以同步的方式进行编写的方法。Kotlin协程的使用步骤包括:创建协程作用域:可以使用或创建协程作用域。创建挂起函数:使用suspend关键字来定义挂起函数。在协程作用域中调用挂起函数:使用launch或async函数来启动协程,这些函数都是挂起函数。挂起函数的使用:在挂起函数中可以使用delay。

shengjiaxin的博客 1007

时序分析-由D触发器结构来理解Tsu、Th

FPGA逻辑单元内的D触发器(D-FF)是一种在时钟的上升沿(或下降沿)将输入信号的变化传送至输出的边沿触发器。 数字电子技术基础-闫石(第五版)边沿D触发器内部结构见下图: 而FPGA原理与结构(日)一书中,内部结构较之上图多了俩反相器: 由传输门和俩个反相器组成一个循环电路(锁存器),再由前后两级锁存器按主从结构链接而成。这里的传输门起开关作用,随着CLK的状态变化切换开关。只看输出的话,前级锁存器的值会随着时钟输入的变化井然有序地传入后级锁存器。为了防止时钟信号变化时输入信号发生冒险,从而使稳定.

XY_Chang的博客 3973

【28】Kotlin语法进阶——使用协程编写高效的并发程序

协程是Kotlin语言中很有代表性的一种并发设计模式,用于简化异步执行的代码。

熊熊饲养员的优快云! 2287

Fluent基于低氧舱气体交换仿真(氮气与空气混合)

一、背景概述 模拟低氧舱充氮气和排除混合气体的过程,假设注入95%的氮气,舱内原有气体为空气,压力为标准大气压,温度为300K。观察气体注入过程中,舱内平均氮气和氧气浓度的变化。 二、Fluent设置 Setup 1、General type选择压力基 绝对速度 瞬态 重力勾选 2、Model 能量方程开启 组分运输开启,设置方法如下: 选择后OK,view就会变成Edit,点击Edit。然后再次点击Edit。 将组分中的非氮气氧气和空气的气体移除,右边选项需要将空气放在最后一位。 3、Materi

qq_35535616的博客 1万+

AI数字人短视频数字人口播数字人分身建模流程全解析

在人工智能与计算机图形学蓬勃发展的当下,数字人建模作为打造虚拟数字人的核心环节,其流程复杂且精妙,融合了多种前沿技术与创意构思,为栩栩如生的数字人形象奠定基石。​。

2403_87518095的博客 1447

Kotlin的协程,延时、超时(7秒后超时,并中断执行的任务)

Kotlin协程 简介: 优点:写法很简单,轻量级,挂起几乎不消耗内存,速度上优于java的线程,性能损耗小,能大幅度提高并发性能,本人推荐使用协程,而不用传统的线程 代码 引入 implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:0.18" 创建一个协程 launch(CommonPool) { //这里需要运行的代...

wy313622821的博客 2万+

⭐⭐⭐全网最详细YOLOv8教程,从环境配置到自己训练,再到数据集的制作,包的各位⭐⭐⭐

问题原因:当你“pip install ultralytics” 时,torch和torchvision会作为它的依赖一起安装了,当执行“pip install torch torchvision torchaudio --index-url。”时,会卸载torch,然后再安装torch+cuda版本,但是不会自动卸载torchvision已有版本,然后再安装torchvision+cuda版本。🎉🎉🎉恭喜各位道友,已经可以训练模型了,现在就是制作自己的数据集,所谓申神通秘境,随心所欲,万物皆可识别也

weixin_74840239的博客 7492

kotlin协程使用举例

Kotlin协程通过简化异步任务的处理,使代码更易于阅读和维护。

shinecjj的博客 496

当启动容器的时候提示:exec format error?如何解决问题

Docker容器出现"exec format error"的主要原因是架构不兼容(如ARM设备运行x86镜像)。解决方案包括:1)匹配镜像与宿主机架构;2)构建时指定平台;3)安装QEMU模拟器;4)修复文件权限和格式;5)验证基础镜像兼容性。排查流程应从检查架构匹配开始,逐步验证权限、解释器和换行符等问题。建议优先使用多架构镜像,构建时明确指定平台,并使用buildx工具生成多平台镜像。调试时可进入容器手动验证文件格式和兼容性。

weixin_39291964的博客 2718

RK3588适配Ubuntu系统

RKsdk上支持buildroot以及Debian系统,但是Ubuntu需要自己移植,有很多公司都移植好了可以直接用,这里就总结记录一下我制作Ubuntu的过程。

m0_60805802的博客 5361

Kotlin 协程第一弹:协程的使用,一文讲清楚!

Kotlin 协程第一弹:协程的使用,一文讲清楚!

idaretobe的专栏 1536

【YOLOv11】从零搭建基于YOLOv11深度学习算法的农作物虫害检测系统(附带环境搭建+完整代码+讲解)

《基于YOLOv11的农作物病虫害智能检测系统》项目摘要 本项目开发了一个基于YOLOv11深度学习算法的农作物病虫害检测系统,支持玉米、水稻、草莓和西红柿等四大类经济作物的30多种病虫害识别。系统采用多模态检测方式,支持图片、视频和实时摄像头输入,并集成了完整的Web应用框架。 技术架构上,系统以PyTorch实现YOLOv11算法为核心,结合Flask搭建深度学习服务,SpringBoot构建业务后端,Vue3+TypeScript开发前端界面,MySQL数据库存储检测数据。系统具备用户权限管理功能,支

AnChenliang_1002的博客 812

Kotlin 协程一 —— 协程 Coroutine

Go、Python 等很多变成语言在语言层面上都实现协程,java 也有三方库实现协程,只是不常用, Kotlin 在语言层面上实现协程,对比 java, 主要还是用来解决异步任务线程切换的痛点。 协程基于线程,但相对于线程轻量很多,可理解为在用户层模拟线程操作; 每创建一个协程,都有一个内核态线程动态绑定,用户态下实现调度、切换,真正执行任务的还是内核线程。 线程的上下文切换都需要内核参与,而协程的上下文切换,完全由用户去控制,避免了大量的中断参与,减少了线程上下文切换与调度消耗的资源。

金戈鐡馬 5485

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

【Android】Kotlin 协程 高效并发详解( Kotlin Coroutine )

协程是一种编程思想,并不局限于特定的语言。除 Kotlin 以外,其他的一些语言,如 Go、Python 等都可以在语言层面上实现协程。 Kotlin Coroutine 本质上是 Kotlin 官方提供的一套线程封装 API,其设计初衷是为了解决并发问题,让协作式多任务实现起来更方便。子任务协作运行,优雅的处理异步问题解决方案。 协程是一种比线程更加轻量级的存在,不是线程,但是可以把它类比成线程。

full courage的博客 6275

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Android Kotlin 协程(coroutine )入门篇

ps:文章会很长 协同程序(coroutine)实在是太好用了,所以我们来学习吧!

我怀里的猫的博客 9469

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

Kotlin协程简介(一)

目录: 一. 协程的基本概念 二. 从异步编程开始 回调 CompletableFuture RxJava 协程 三. 协程的基本概念 suspend funtion CoroutineScope CoroutineContext CoroutineDispatcher Job 和 Deffered Coroutine builders 一. 协程的基本概念 协程就像非常轻量级的...

heihei 4928

Kotlin协程的使用

目录 引入kotlin协程 kotlin协程的三种启动方式 初识协程: 第一种启动方式(runBlocking:T) 第二种启动方式(launch:Job) 第三种启动方式(async/await:Deferred) 实现你的第一个Coroutine程序 浅析Kotlin协程 ——协程是什么?https://blog.youkuaiyun.com/qq_17798399/article/det...

青冘的技术学习博客 1万+

Kotlin协程(Coroutine)中关于yield的解释

如果你在关注kotlin并且也在关注Coroutine 那么你肯定在官网上看到了 这样的代码: val job = launch { val child = launch { try { delay(Long.MAX_VALUE) } finally { println("Child is cancelled...

weixin_42215792的博客 6649

coroutine倒计时 kotlin_Kotlin学习教程之协程Coroutine

定义Coroutine翻译为协程,Google翻译为协同程序,一般也称为轻量级线程,但需要注意的是线程是操作系统里的定义概念,而协程是程序语言实现的一套异步处理的方法。在Kotlin文档中,Coroutine定义为一个可被挂起的计算实例,下面话不多说了,来一起看看详细的介绍吧。配置build.gradle中dependencies 添加下面2行,注意coroutine目前仍处于experiment...

weixin_39595430的博客 1533

kotlin Coroutine协程

kotlin Coroutine协程什么是协程?官方描述:协程起源些语言应用到了协程?协程优点举例说明异步代码 & 回调地狱地狱到天堂(使用协程)什么是进程和线程?进程是什么呢?线程又是什么呢?Java中线程具有五种状态线程和协程的关系开始使用环境准备创建协程的几种方式使用方式一:launch:Job(最常用,不阻塞)使用方式二:runBlocking(阻塞)使用方式三:async/await:Deferred(不阻塞)协程中的一些关键名称关系调度器Dispatcherssuspend 什么是协程

LeifuCode博客 965

深入理解 Kotlin Coroutine (一)

1. 什么是 Coroutine Coroutine 被翻译成了“协程”,意思就是要各个子任务协作运行的意思,所以大家一下就明白了它被创造出来是要解决异步问题的。 我们写 Java 的程序员,对线程更熟悉一些。线程是比进程更小一级的运行单位,它的调度由操作系统来完成,所以我们只管 new Thread 和 start,至于什么时候 run,什么时候 run 完,我们都没办法预见。 Thr...

android开发笔记 1327

Android Kotlin之Coroutine(协程)详解

协程Coroutine是一种并发设计模式,您可以在 Android 平台上(Kotlin)使用它来简化异步执行的代码。在 Android Kotlin 上,协程Coroutine有助于管理长时间运行的任务,如果管理不当,这些任务可能会阻塞主线程并导致应用无响应。协程可以类似于RxJava那样,做到异步任务同步化,避免可能出现的回调地狱。同时,通过关键字来标识函数,称为挂起函数,该函数,只能在协程或其他的suspend函数中执行,从而保证主线程的安全。下面,我们先写个简单协程。协程多了2个状态。

蜗牛快跑 6576

你真的懂协程吗 ? Kotlin 协程 Coroutine 全解析

协程是什么?协程并不是一个新的概念,它并不是 Kotlin 发明的。它们已经存在了几十年,并且在 Go 等其他一些编程语言中很受欢迎。协程(英语:Cor...

AI天才研究院 9268
上一篇: Room-数据持久化存储(进阶)
下一篇: Kotlin Coroutine(协程): 二、初识协程
孟老板007
博客等级 码龄5年 19粉丝 27原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值