Android kotlin协程

说明

  • 可代替线程整异步
  • 可控制,灵活 (控制优先级,内存占用等)
  • 速度快 效率高
  • 有数量上限

使用

  • runBlocking 一般用于测试 不建议使用
  • GlobalScope.launch 全局的 生命周期跟随application 不建议使用
  • CoroutineScope(job) 用
    基本使用
  runBlocking {Log.i("test_coroutine","我是一个runBlocking")}Log.i("test_coroutine","我在 runBlocking 协程外 且在 协程后")GlobalScope.launch {Log.i("test_coroutine","我是一个GlobalScope")}Log.i("test_coroutine","我在 GlobalScope 协程外 且在 协程后")val job = Job()val coroutineScope = CoroutineScope(job)coroutineScope.launch {Log.i("test_coroutine","我是一个coroutineScope")}Log.i("test_coroutine","我在 coroutineScope 协程外 且在 协程后")

结果
在这里插入图片描述
分析

runBlocking 阻塞主线程 执行了协程后 继续执行

GlobalScope.launch 不阻塞 继续执行主线程 后执行协程
coroutineScope.launch 不阻塞 继续执行主线程 后执行协程

  • 增加延时,效果更明显 delay(1000)
  runBlocking {delay(1000)Log.i("test_coroutine","我是一个runBlocking")}Log.i("test_coroutine","我在 runBlocking 协程外 且在 协程后")GlobalScope.launch {delay(1000)Log.i("test_coroutine","我是一个GlobalScope")}Log.i("test_coroutine","我在 GlobalScope 协程外 且在 协程后")val job = Job()val coroutineScope = CoroutineScope(job)coroutineScope.launch {delay(1000)Log.i("test_coroutine","我是一个coroutineScope")}Log.i("test_coroutine","我在 coroutineScope 协程外 且在 协程后")

结果
在这里插入图片描述
分析

runBlocking 阻塞主线程 执行了协程后 继续执行

GlobalScope.launch 协程内容最后执行
coroutineScope.launch 协程内容最后执行

1.1 协程里的挂起

 val coroutineScope = CoroutineScope(Job())val job = coroutineScope.launch {delay(1000)Log.i("test_coroutine","我是一个coroutineScope")      //1launch {delay(1000)Log.i("test_coroutine","我是一个coroutineScope 里的 launch")  // 4delay(1000)Log.i("test_coroutine","我是一个coroutineScope 里的 launch1")  //5}Log.i("test_coroutine","我是一个coroutineScope1")  // 2Log.i("test_coroutine","我是一个coroutineScope2")  // 3}

结果
在这里插入图片描述
继续玩

 val coroutineScope = CoroutineScope(Job())val job = coroutineScope.launch {delay(1000)Log.i("test_coroutine","我是一个coroutineScope")   //1launch {delay(1000)Log.i("test_coroutine","我是一个coroutineScope 里的 launch")  //3delay(1000)Log.i("test_coroutine","我是一个coroutineScope 里的 launch1")  //5}Log.i("test_coroutine","我是一个coroutineScope1")  //2delay(1500)                                          //多了个delayLog.i("test_coroutine","我是一个coroutineScope2")  //4}

结果
在这里插入图片描述

  • join()
 val coroutineScope = CoroutineScope(Job())val job = coroutineScope.launch {delay(1000)Log.i("test_coroutine","我是一个coroutineScope")  //1val job1 = launch {delay(1000)Log.i("test_coroutine","我是一个coroutineScope 里的 launch")  //3delay(1000)Log.i("test_coroutine","我是一个coroutineScope 里的 launch1")  //4}Log.i("test_coroutine","我是一个coroutineScope1")  //2job1.join()delay(1500)                                          //多了个delayLog.i("test_coroutine","我是一个coroutineScope2")  //5}

结果: 执行的时候 job1加入了进来
在这里插入图片描述

  • cancel()
 val coroutineScope = CoroutineScope(Job())val job = coroutineScope.launch {delay(1000)Log.i("test_coroutine","我是一个coroutineScope")  //1val job1 = launch {delay(1000)Log.i("test_coroutine","我是一个coroutineScope 里的 launch")  //3delay(1000)Log.i("test_coroutine","我是一个coroutineScope 里的 launch1")  //不执行}Log.i("test_coroutine","我是一个coroutineScope1")  //2delay(1500)                                          //多了个delayLog.i("test_coroutine","我是一个coroutineScope2")  //4cancel()}

结果 job 和 子job1都停了
在这里插入图片描述

  • job1.cancel()
 val coroutineScope = CoroutineScope(Job())val job = coroutineScope.launch {delay(1000)Log.i("test_coroutine","我是一个coroutineScope")val job1 = launch {delay(1000)Log.i("test_coroutine","我是一个coroutineScope 里的 launch")delay(1000)Log.i("test_coroutine","我是一个coroutineScope 里的 launch1")}Log.i("test_coroutine","我是一个coroutineScope1")delay(1500)                                          //多了个delayLog.i("test_coroutine","我是一个coroutineScope2")job1.cancel()Log.i("test_coroutine","我是一个coroutineScope3")}

结果 job继续执行 job1停了
在这里插入图片描述

  • job1.cancelAndJoin() 执行完之后 取消
  val coroutineScope = CoroutineScope(Job())val job = coroutineScope.launch {delay(1000)Log.i("test_coroutine","我是一个coroutineScope")val job1 = launch {var i = 0while(i<10){yield()delay(500)Log.i("test_coroutine","我是一个coroutineScope 里的 launch>>${i++}")}}Log.i("test_coroutine","我是一个coroutineScope1")delay(1500)                                          //多了个delayLog.i("test_coroutine","我是一个coroutineScope2")job1.join()job1.cancel()Log.i("test_coroutine","我是一个coroutineScope3")}

结果 job1并没有被取消
在这里插入图片描述

  • job1.cancelAndJoin()
   val coroutineScope = CoroutineScope(Job())val job = coroutineScope.launch {delay(1000)Log.i("test_coroutine","我是一个coroutineScope")val job1 = launch {var i = 0while(i<10){yield()delay(500)Log.i("test_coroutine","我是一个coroutineScope 里的 launch>>${i++}")}}Log.i("test_coroutine","我是一个coroutineScope1")delay(1500)                                          //多了个delayLog.i("test_coroutine","我是一个coroutineScope2")job1.cancelAndJoin()Log.i("test_coroutine","我是一个coroutineScope3")}

结果
在这里插入图片描述

  • ensureActive() 在协程不在 active 状态时会立即抛出异常。

  • yield() yield 会进行的第一个工作就是检查任务是否完成,如果 Job 已经完成的话,就会抛出 CancellationException 来结束协程。yield 应该在定时检查中最先被调用

  • async

 val async = async {var i = 0while(i<10 && isActive){delay(500)Log.i("test_coroutine","我是一个coroutineScope 里的 launch>>${i++}")}"完事啦"}Log.i("test_coroutine","我是一个coroutineScope1")delay(1500)                                          //多了个delayLog.i("test_coroutine","我是一个coroutineScope2")val result = async.await()Log.i("test_coroutine","我是一个coroutineScope3 result>"+result)Log.i("test_coroutine","我是一个coroutineScope4")

结果
在这里插入图片描述

  • withTimeout
 Log.i("test_coroutine","我是一个coroutineScope")withTimeout(3000){var i = 0while(i<10 && isActive){delay(500)Log.i("test_coroutine","我是一个coroutineScope 里的 launch>>${i++}")}}Log.i("test_coroutine","我是一个coroutineScope1")delay(1500)                                          //多了个delayLog.i("test_coroutine","我是一个coroutineScope2")

结果 时间到后所在的协程也不继续执行了
在这里插入图片描述

Android中的协程

  • MainScope
MainScope().launch {}
  • viewModelScope
    implementation ‘androidx.lifecycle:lifecycle-viewmodel-android:2.8.0’
    implementation ‘androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.0’
    implementation ‘androidx.lifecycle:lifecycle-common:2.8.0’
 viewModelScope.launch {}
  • lifecycleScope
  lifecycleScope.launch {}

在这里插入图片描述

  • rememberCoroutineScope() 可能会因为组件状态变化而移除此协程
@Composable
inline fun rememberCoroutineScope(crossinline getContext: @DisallowComposableCalls () -> CoroutineContext ={ EmptyCoroutineContext }
): CoroutineScope {val composer = currentComposerval wrapper = remember {CompositionScopedCoroutineScopeCanceller(createCompositionCoroutineScope(getContext(), composer))}return wrapper.coroutineScope
}
  • currentRecomposeScope currentRecomposeScope 是一个在任何Composable函数中都能访问的成员
    作用是使当前时刻组合无效,强制触发重组
val currentRecomposeScope: RecomposeScope@ReadOnlyComposable@OptIn(InternalComposeApi::class)@Composable get() {val scope = currentComposer.recomposeScope ?: error("no recompose scope found")currentComposer.recordUsed(scope)return scope}
  • supervisorScope 协程异常不影响其他协程
  • coroutineScope 有异常所有携程都退出

本文参考 https://blog.csdn.net/Code1994/article/details/129448142

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/15474.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

樱花下落的速度是每秒5厘米,我们的心又该以什么速度去接近呢

樱花下落的速度是每秒五厘米。5年前第一次接触秒速五厘米的时候&#xff0c;我还在念初中&#xff0c;那时候的我尚且理解不了作品里的太多东西&#xff0c;只是为那辆列车隔开了明里和贵树感到悲伤&#xff0c;为他们二人那段无疾而终的感情感到遗憾。五年后再一次重温&#x…

GEE批量导出逐日、逐月、逐季节和逐年的遥感影像(以NDVI为例)

影像导出 1.逐日数据导出2.逐月数据导出3.季节数据导出4.逐年数据导出 最近很多小伙伴们私信我&#xff0c;问我如何高效导出遥感数据&#xff0c;从逐日到逐季度&#xff0c;我都有一套自己的方法&#xff0c;今天就来和大家分享一下&#xff01;   &#x1f50d;【逐日导出…

Scala 入门介绍和环境搭建

一、简介 Scala 是一门以 Java 虚拟机&#xff08;JVM&#xff09;为运行环境并将面向对象和函数式编程的最佳特性结合在一起的静态类型编程语言 (静态语言需要提前编译&#xff0c;如&#xff1a;Java、c、c 等&#xff0c;动态语言如&#xff1a;js)Scala 是一门多范式的编程…

【介绍下Pwn,什么是Pwn?】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

CSS3文字与字体

文字与字体 @font-face 用途:定义一种自定义字体,使其可以在网页中使用。通过@font-face规则,可以指定字体名称、来源(通常是URL)以及字体的各种变体(如常规、粗体、斜体等)。 @font-face {font-family: MyCustomFont;src: url(mycustomfont.woff2) format(woff2

冯喜运:5.25黄金价格和原油价格加速看跌?未来如何走势?

【黄金消息面分析】&#xff1a;本周黄金市场经历剧烈波动&#xff0c;金价创下五个半月来最糟糕的单周表现&#xff0c;尽管周五因美元下跌小幅回升。美联储的鹰派立场和美国经济数据强劲削弱了降息预期&#xff0c;导致金价承压。然而&#xff0c;分析师对未来金价走势看法不…

Rolla‘s homework:Image Processing with Python Final Project

对比学习Yolo 和 faster rcnn 两种目标检测 要求 Image Processing with Python Final Project Derek TanLoad several useful packages that are used in this notebook:Image Processing with Python Final Project Project Goals: • Gain an understanding of the object …

leetcode 1049.最后一块石头的重量II

思路&#xff1a;01背包 其实这道题我们可以转化一下&#xff0c;乍一看有点像区间dp&#xff0c;很像区间合并那种类型。 但是&#xff0c;后来发现&#xff0c;这道题的精髓在于你如何转成背包问题。我们可以把这个石头分成两堆&#xff0c;然后求出来这两堆的最小差值就行…

使用git生成SSH公钥,并设置SSH公钥

1、在git命令行里输入以下命令 ssh-keygen -t rsa 2、按回车&#xff0c;然后会看到以下字眼 Generating public/private rsa key pair. Enter file in which to save the key (/c/Users/xxx/.ssh/id_rsa) 例&#xff1a; 3、继续回车&#xff0c;然后会看到以下字眼 Enter…

【面试干货】数据库乐观锁,悲观锁的区别,怎么实现

【面试干货】数据库乐观锁&#xff0c;悲观锁的区别&#xff0c;怎么实现 1、乐观锁&#xff0c;悲观锁的区别2、总结 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 1、乐观锁&#xff0c;悲观锁的区别 悲观锁&#xff08;Pessimistic Lo…

web前端框架设计第十课-组件

web前端框架设计第十课-组件 一.预习笔记 组件&#xff1a;Vue最强大的功能之一 1.局部组件注册 注意事项&#xff1a;template标签中只能有一个根元素 2.全局组件的注册 注意事项&#xff1a;组件名的大小写需要注意&#xff08;实践&#xff09; 3.案例&#xff08;查询框…

Vivado 使用教程(个人总结)

Vivado 是 Xilinx 公司推出的一款用于 FPGA 设计的集成开发环境 (IDE)&#xff0c;提供了从设计输入到实现、验证、调试和下载的完整流程。本文将详细介绍 Vivado 的使用方法&#xff0c;包括项目创建、设计输入、约束文件、综合与实现、仿真、调试、下载配置等步骤。 一、创建…

设计模式--责任链模式

责任链模式是一种行为设计模式&#xff0c;它允许将请求沿着处理者链进行发送。请求会沿链传递&#xff0c;直到某个处理者对象负责处理它。这种模式在许多应用场景中非常有用&#xff0c;例如在处理用户输入、过滤请求以及实现多级审核时。 应用场景 处理用户输入&#xff1…

kafka之consumer参数auto.offset.reset

Kafka的auto.offset.reset 参数是用于指定消费者在启动时如何处理偏移量&#xff08;offset&#xff09;的。这个参数有三个主要的取值&#xff1a;earliest、latest和none。 earliest&#xff1a; 当各分区下有已提交的offset时&#xff0c;从提交的offset开始消费&#xff1b…

HCIP-VLAN综合实验

一、实验拓扑 二、实验要求 1、pc1和pc3所在接口为access;属于vlan 2; PC2/PC4/PC5/PC6处于同一网段’其中PC2可以访问PC4/PC5/PC6; PC4可以访问PC6&#xff1b;PC5不能访问PC6&#xff1b; 2、PC1/PC3与PC2/PC4/PC5/PC6不在同一个网段&#xff1b; 3、所有PC通过DHCP获取IP…

栈和队列的应用-计算器实例

‘’‘ &#xff08;11 3&#xff09; 2 -5 顺序存储栈来实现 ’‘’ sqstack.h #ifndef SQSTACK_H__ #define SQSTACK_H__ #define MAXSIZE 32 typedef int datatype typedef struct node_st {datatype data[MAXSIZE]; int top;}sqstack;sqstack *st_create(void); int s…

闲话 .NET(5):.NET Core 有什么优势?

前言 .NET Core 并不是 .NET FrameWork 的升级版&#xff0c;它是一个为满足新一代的软件设计要求而从头重新开发的开发框架和平台&#xff0c;所以它没有 .NET FrameWork 的历史包袱&#xff0c;相对于 .NET FrameWork&#xff0c;它具备很多优势。 .NET Core 有哪些优势&am…

智算中心带宽漫谈 -- 开篇

隐秘的角落 带宽对高性能计算是一个永恒的话题&#xff0c;本质上&#xff0c;带宽即数据交换的速率&#xff0c;单位时间的传输数据越多&#xff0c;带宽就越高&#xff0c;但对高性能计算来说&#xff0c;对高带宽的渴求永无止境&#xff0c;好比宏观现实世界中的车道&#…

QT实现线程的四种方式(QThread、QRunnable和QThreadPool、QObject、QtConcurrent)

在当今高性能计算需求日益增长的背景下,多线程编程已成为提升应用性能的重要手段。Qt框架,作为一个功能全面、跨平台的C++应用程序开发工具包,为我们提供了多种多线程实现方案。本文将介绍QThread类在Qt多线程编程中的应用,以及如何通过QRunnable和QThreadPool、QObject的m…

C# GDI+ 绘制文字不同的操作系统渲染文字大小不同

一、C# GDI 绘制文字不同的操作系统渲染文字大小不同 原因&#xff1a;使用Font 字体的时候&#xff0c;没有指定字体渲染的单位。 不同系统的默认字体单位会不同。 二、解决方案&#xff1a; 在指定字体的时候&#xff0c;指定字体大小&#xff0c;同时也要设置字体的单位 …