Android kotlin协程

news2025/3/17 0:47:00

说明

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

使用

  • 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")      //1
        launch {
            delay(1000)
            Log.i("test_coroutine","我是一个coroutineScope 里的 launch")  // 4
            delay(1000)
            Log.i("test_coroutine","我是一个coroutineScope 里的 launch1")  //5
        }

        Log.i("test_coroutine","我是一个coroutineScope1")  // 2
        Log.i("test_coroutine","我是一个coroutineScope2")  // 3
    }

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

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

        Log.i("test_coroutine","我是一个coroutineScope1")  //2
        delay(1500)                                          //多了个delay
        Log.i("test_coroutine","我是一个coroutineScope2")  //4
    }

结果
在这里插入图片描述

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

        Log.i("test_coroutine","我是一个coroutineScope1")  //2
        job1.join()
        delay(1500)                                          //多了个delay
        Log.i("test_coroutine","我是一个coroutineScope2")  //5
    }

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

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

        Log.i("test_coroutine","我是一个coroutineScope1")  //2
        delay(1500)                                          //多了个delay
        Log.i("test_coroutine","我是一个coroutineScope2")  //4
        cancel()
    }

结果 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)                                          //多了个delay
        Log.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 = 0
            while(i<10){
                yield()
                delay(500)
                Log.i("test_coroutine","我是一个coroutineScope 里的 launch>>${i++}")
            }
        }

        Log.i("test_coroutine","我是一个coroutineScope1")
        delay(1500)                                          //多了个delay
        Log.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 = 0
            while(i<10){
                yield()
                delay(500)
                Log.i("test_coroutine","我是一个coroutineScope 里的 launch>>${i++}")
            }
        }

        Log.i("test_coroutine","我是一个coroutineScope1")
        delay(1500)                                          //多了个delay
        Log.i("test_coroutine","我是一个coroutineScope2")
        job1.cancelAndJoin()
        Log.i("test_coroutine","我是一个coroutineScope3")
    }

结果
在这里插入图片描述

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

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

  • async

 val async = async {
            var i = 0
            while(i<10 && isActive){
                delay(500)
                Log.i("test_coroutine","我是一个coroutineScope 里的 launch>>${i++}")
            }
            "完事啦"
        }


        Log.i("test_coroutine","我是一个coroutineScope1")
        delay(1500)                                          //多了个delay
        Log.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 = 0
            while(i<10 && isActive){
                delay(500)
                Log.i("test_coroutine","我是一个coroutineScope 里的 launch>>${i++}")
            }
        }


        Log.i("test_coroutine","我是一个coroutineScope1")
        delay(1500)                                          //多了个delay
        Log.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 = currentComposer
    val 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.coloradmin.cn/o/1695015.html

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

相关文章

C结构详解

目录 1、结构模板 1. 建立结构声明 2. 定义结构变量 3. 访问结构成员 4. 初始化结构 声明结构数组 声明和初始化结构指针 1、结构模板 1. 建立结构声明 struct book{char title[MAXTITL];char author[MAXAUTL];float value; }&#xff1b; 该声明描述了一个又两个字符…

指北者智能音乐学习机隆重亮相广州国际乐器展

2024年5月23-26日广州国际乐器展览会在广交会展馆B区隆重开幕&#xff0c;本届展会开设5大展厅、50000平方米的主题展区&#xff0c;吸引了700多家国内外参展商参展&#xff0c;打造集展示、商贸、文化交流、文娱于一体的广阔平台。深圳市指北科技有限公司也携旗下品牌指北者智…

plt多子图设置

import matplotlib.pyplot as plt# 使用 subplots 函数创建一个 2x3 的子图网格 fig, axs plt.subplots(nrows2, ncols3, figsize(16, 10)) # 调整 figsize 来改变图像大小# 遍历每个子图&#xff0c;并绘制一些内容&#xff08;这里只是简单的示例&#xff09; for ax in ax…

leetcode230 二叉搜索树中第K小的元素

题目 给定一个二叉搜索树的根节点 root &#xff0c;和一个整数 k &#xff0c;请你设计一个算法查找其中第 k 个最小元素&#xff08;从 1 开始计数&#xff09;。 示例 输入&#xff1a;root [5,3,6,2,4,null,null,1], k 3 输出&#xff1a;3 解析 这道题应该是能做出…

计算机网络-BGP概述

一、概述 到目前为止我们已经学习了静态路由、OSPF、RIP、IS-IS了&#xff0c;前面我们也了解到按照区域或者范围来分&#xff0c;路由协议可以划分为&#xff1a;IGP内部网关协议、EGP外部网关协议&#xff0c;而我们前面学习的动态路由都属于IGP的范畴. IGP是用于单一自治系统…

AI大模型探索之路-训练篇25:ChatGLM3微调实战-基于LLaMA-Factory微调改造企业级知识库

系列篇章&#x1f4a5; AI大模型探索之路-训练篇1&#xff1a;大语言模型微调基础认知 AI大模型探索之路-训练篇2&#xff1a;大语言模型预训练基础认知 AI大模型探索之路-训练篇3&#xff1a;大语言模型全景解读 AI大模型探索之路-训练篇4&#xff1a;大语言模型训练数据集概…

NetSuite Intercompany COGS科目设置问题

在22年底的NetSuite多公司功能串讲中&#xff0c;有一个题目是Intercompany COGS科目的设置问题。近期在项目上这个问题被密集讨论。为了方便分享&#xff0c;所以在此摘出来独立成文。有兴趣的同学也可以翻看之前的视频。 NetSuite知识会 第8谈 多公司功能串讲 NetSuite Inter…

性能测试--线程的监控

1.线程的状态 1.1.线程的5种状态 java的线程总共有5种状态&#xff0c;如下&#xff1a; * 新建&#xff1a;new 【新建之后不启用都是new】* 运行&#xff1a;runnable* 等待&#xff1a;waitting(无限期等待),timed waitting(限期等待)* 阻塞&#xff1a;blocked* 结束&am…

1.存储部分

1.Flash Memory--闪速存储器&#xff08;注&#xff1a;U盘&#xff0c;SD卡就是闪存&#xff09;在EEPROM基础上发展而来的&#xff0c;断电后也能保存信息&#xff0c;且可进行多次 快速擦除重写。注意&#xff1a;由于闪存需要先擦除再写入&#xff0c;因此闪存写的速度要比…

[less配置]vue2引入less

1、终端输入&#xff1a;npm install less less-loader --save-dev 2、在package.json查看是否安装less依赖 3、调用

Add object from object library 从对象库中添加内置器件

Add object from object library 从对象库中添加内置器件 正文正文 对于 Lumerical,有些时候我们在使用中,可能需要从 Object library 中添加器件,通常我们的做法是手动添加。如下图所示,我们添加一个 Directional Coupler 到我们的工程文件中: 但是这种操作方式不够智能…

基于附带Attention机制的seq2seq模型架构实现英译法的案例

模型架构 先上图 我们这里选用GRU来实现该任务&#xff0c;因此上图的十个方框框都是GRU块&#xff0c;如第二张图&#xff0c;放第一张图主要是强调编码器的输出是作用在解码器每一次输入的观点&#xff0c;具体的详细流程图将在代码实现部分给出。 编码阶段 1. 准备工作…

Element Plus (面向外卖编程)

Element介绍 使用流程 案例 Element介绍 是饿了么团队基于 Vue 3 研发的面向设计师和开发者的组件库&#xff0c;访问官网能使用到各种组件样式 组件&#xff1a;组成网页的部件&#xff0c;例如 超链接、按钮、图片、表格、表单、分页条等等。官网&#xff1a;https://…

AI多模态「六边形战士」,原创音乐、1分钟百页PPT、抖音爆款……

2024年AI行业最大的看点是什么&#xff1f; 那一定是多模态AI应用。 大模型发展到今天这个阶段&#xff0c;文本处理已经是各家大模型的必备技能了&#xff0c;对音频、视觉等多模态的理解和应用才是下一个阶段大模型比拼的赛道。 3.5研究测试&#xff1a;hujiaoai.cn 4研究测…

测试驱动编程(3)进阶单元测试(下)

文章目录 测试驱动编程(3)进阶单元测试&#xff08;下&#xff09;示例实战接收同事的需求开始迭代需求故事迭代1故事迭代2故事迭代3故事迭代4故事迭代5故事迭代6 测试驱动编程(3)进阶单元测试&#xff08;下&#xff09; 示例实战 接收同事的需求 你的同事正在开发一个远程…

前端 防抖和节流

在前端开发中&#xff0c;防抖&#xff08;Debounce&#xff09;和节流&#xff08;Throttle&#xff09;是两种常用的性能优化技术&#xff0c;尤其在处理频繁触发的事件时显得尤为重要。无论是在用户输入、窗口调整大小&#xff0c;还是滚动事件中&#xff0c;这两种技术都可…

el-transfer和el-tree进行结合搞一个树形穿梭框

由于业务需求需要在穿梭框里使用树形结构&#xff0c;但是本身element里并不支持&#xff0c;于是参考了别的大佬发的文章作为思路及后续自己新增了一些处理功能。 目录 1.拷贝代码放到自己的项目目录中 2.改造el-transfer的源码 3.修改tree-transfer-panel.vue文件 4.修改…

C语言内存函数超详细讲解

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 C语言内存函数超详细讲解 收录于专栏【C语言学习】 本专栏旨在分享学习C语言学习的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 目录 1. m…

IDEA打开项目报错

IDEA打开项目报错&#xff1a; Cannot read scheme C:\Users\xxxxxx\AppData\Roaming\JetBrains\IntelliJIdea2023.2\qaplug_profiles\Default.xmljava.lang.AbstractMethodError: Receiver class com.soldevelo.qaplug.scanner.AnalysisProfileManager$2 does not define or i…

浅谈后端boot框架整合第三方技术JUnit MyBatis Druid整体思想

整合第三方技术 不要单单学习指定技术与springboot整合的方式 学习目标的是整合整体的技术的思路 拿到任何一个第三方技术后我们在springboot中如何操作 这是真正我们应该学习的东西 以后能整合任意技术 整合JUnit JUnit 是一个流行的开源测试框架&#xff0c;用于 Java …