协程的基本概念及用法
协程的基本概念及用法协程的基本概念及用法1. 阅读前问题卡Kotlin 协程1.1 阅读前先看这几个问题1.2 读完后完成这 3 个任务1.2.1 任务 1说明协程与线程的关系1.2.2 任务 2区分协程创建、切换与挂起1.2.3 任务 3走读请求示例的状态变化1.3 自检清单2. 协程是什么3. 协程与线程的关系4. 协程的基本使用4.1 使用 launch 方法4.2 使用 withContext 方法4.3 使用 suspend 关键字5. 获取协程的返回值5.1 async / await5.2 suspendCoroutine6. 协程的非阻塞式挂起7. 代码示例1. 阅读前问题卡Kotlin 协程建议先读先读“协程是什么”和“协程与线程的关系”再依次阅读launch、withContext与suspend三个小节。1.1 阅读前先看这几个问题文档如何界定 Kotlin 协程它与线程和进程分别是什么关系为什么单线程中使用协程不会缩短总执行时间Android 主线程上的耗时操作又为什么仍需切换线程runBlocking、GlobalScope.launch和自行创建CoroutineScope这 3 种方式各有什么适用边界launch、withContext和suspend分别负责创建协程、切换线程和限制调用位置中的哪一部分协程执行到suspend方法时线程和协程各自如何继续执行完成后又如何resumeasync / await与suspendCoroutine在是否创建协程、返回结果和提交异常方面有什么区别代码示例中的请求状态如何从IDLE变为LOADING再进入SUCCESS或FAIL期间在哪些线程执行1.2 读完后完成这 3 个任务1.2.1 任务 1说明协程与线程的关系做什么用自己的话复述协程、线程和进程的关系并解释文档所说的“协作式多任务”。验证标准能用不超过 4 句话说明代码运行层级、协程依赖线程、单线程总耗时和 Android 主线程切换要求。1.2.2 任务 2区分协程创建、切换与挂起做什么整理一张小表对比runBlocking、GlobalScope.launch、CoroutineScope.launch、withContext和suspend的作用。验证标准每项都能写出“是否创建协程、是否切换线程、是否阻塞或限制调用位置”中的适用结论并能对应到正文依据。1.2.3 任务 3走读请求示例的状态变化做什么从simulateNetworkRequest()开始按执行顺序标出状态更新、协程启动、IO 线程切换、结果返回和 Compose 界面读取状态的位置。验证标准能画出IDLE → LOADING → SUCCESS / FAIL的状态路径并指出viewModelScope.launch、async / await、withContext(Dispatchers.IO)和collectAsState()各自所在步骤。1.3 自检清单我能用一句话说明本文语境下的 Kotlin 协程是什么。我能说明协程、线程和进程之间的关系。我能区分 3 种协程创建方式的特点和使用边界。我能解释launch、withContext、suspend、挂起和恢复之间的关系。我能比较async / await与suspendCoroutine的用途。我能沿着示例代码复述请求状态、线程切换和界面更新流程。2. 协程是什么协程是一种编程思想并不局限于特定的语言。除 Kotlin 以外其他的一些语言如 Go、Python 等都可以在语言层面上实现协程。Kotlin Coroutine 本质上是 Kotlin 官方提供的一套线程封装 API其设计初衷是为了解决并发问题让“协作式多任务”实现起来更方便。3. 协程与线程的关系从 Android 开发者的角度去理解它们之间的关系我们所有的代码跑在线程中而线程跑在进程中。协程也是跑在线程中的可以是单线程也可以是多线程。单线程中协程的总执行时间并不会比不用协程少。Android 系统上在主线程上进行耗时操作如网络请求即使用了协程也需要切换线程。4. 协程的基本使用4.1 使用 launch 方法协程在写法上和普通的顺序代码类似可以让开发者用同步的方式写出异步的代码。创建协程可以使用以下 3 种方式runBlocking{// 方法1使用 runBlocking 顶层函数}GlobalScope.launch{// 方法2使用 GlobalScope 单例对象调用 launch 开启协程}valcoroutineScopeCoroutineScope(context)coroutineScope.launch{// 方法3自行通过 CoroutineContext 创建一个 CoroutineScope 对象}方法 1 适用于单元测试场景实际开发中不使用因为它是线程阻塞的。方法 2 与runBlocking相比不会阻塞线程但它的生命周期会和 APP 一致且无法取消。方法 3 比较推荐使用可以通过context参数去管理和控制协程的生命周期。此处的launch方法含义是创建一个新的协程并在指定的线程上运行它。传给launch方法的连续代码段就被叫做一个协程传给launch方法的方法参数可以用于指定执行这段代码的线程。coroutineScope.launch(Dispatchers.IO){// 可以通过 Dispatchers.IO 参数把任务切到 IO 线程执行}coroutineScope.launch(Dispatchers.Main){// 也可以通过 Dispatchers.Main 参数切换到主线程}4.2 使用 withContext 方法这个方法可以切换到指定的线程并在闭包内的逻辑执行结束之后自动把线程切换回去继续执行如下所示coroutineScope.launch(Dispatchers.Main){// 在 UI 线程开始valimagewithContext(Dispatchers.IO){// 切换到 IO 线程getImage(imageId)// 在 IO 线程执行}imageView.setImageBitmap(image)// 回到 UI 线程更新 UI}该方法支持自动切回原来的线程能够消除并发代码在协作时产生的嵌套。如果需要频繁地进行线程切换这种写法将有很大的优势这就是“使用同步的方式写异步代码”。4.3 使用 suspend 关键字我们可以把withContext单独放进一个方法里面此方法需要使用suspend关键字标记才能编译通过suspendfungetImage(imageId:Int)withContext(Dispatchers.IO){}使用launch、async等方法创建的协程在执行到某个suspend方法时会从正在执行它的线程上脱离。互相脱离后的线程和协程将会分别执行不同的任务线程线程执行到了suspend方法就暂时不再执行剩余协程代码跳出协程的代码块。如果它是一个后台线程它会被系统回收或者再利用继续执行别的后台任务与 Java 线程池中的线程等同如果它是 Android 主线程它会继续执行界面刷新任务。协程协程会从上面被挂起的suspend方法开始在该方法的参数指定的线程如Dispatchers.IO所指定的 IO 线程中继续往下执行。suspend方法执行完成之后会重新切换回它原先的线程。这个“切回来”的动作在 Kotlin 中叫做resume。suspend关键字只是一个提醒为了让它包含真正挂起的逻辑要在它内部直接或间接调用 Kotlin 自带的suspend方法。该关键字本身只有一个效果限制这个方法只能在协程里或者另一个suspend方法中被调用否则就会编译不通过。5. 获取协程的返回值协程是一种异步的概念需要一些特殊操作才能获取返回值。获取协程的返回值可以使用以下方式5.1 async / await主要流程是使用async开启协程然后调用async返回的Deferred对象的await方法获取协程运算的结果coroutineScope.launch(Dispatchers.IO){valjobasync{delay(1000)returnasyncreturn value}println(async result${job.await()})}5.2 suspendCoroutine与async不同suspendCoroutine只是一个挂起方法无法开启协程需要在其他协程作用域中使用。协程运行结束后使用resume提交返回值或使用resumeWithException抛出异常。coroutineScope.launch(Dispatchers.IO){try{valresultsuspendCoroutineString{delay(1000)valrandomRandom().nextBoolean()if(random){it.resume(return value)}else{it.resumeWithException(Exception(Coroutine Failure))}}println(suspendCoroutine success result:$result)}catch(e:java.lang.Exception){println(suspendCoroutine failure exception:$e)}}6. 协程的非阻塞式挂起“非阻塞式挂起”指的就是协程在挂起的同时切线程这件事情。使用了协程的代码看似阻塞但由于协程内部做了很多工作包括自动切换线程它实际上是非阻塞的。在代码执行的过程中线程虽然会切换但写法上类似普通的单线程代码。在 Kotlin 中协程就是基于线程来实现的一种更上层的工具 API类似于 Android 自带的 Handler 系列 API。在设计思想上协程是一个基于线程的上层框架。Kotlin 协程并没有脱离 Kotlin 或者 JVM 创造新的东西只是简化了多线程的开发。7. 代码示例使用协程模拟实现一个网络请求等待时显示 Loading请求成功或者出错让 Loading 消失并将状态反馈给用户。在ViewModel中编写如下业务逻辑代码HiltViewModelclassMainViewModelInjectconstructor():ViewModel(){enumclassRequestStatus{IDLE,LOADING,SUCCESS,FAIL}valrequestStatusMutableStateFlow(RequestStatus.IDLE)/** * 模拟网络请求并将状态设置给 requestStatus 变量 */funsimulateNetworkRequest(){requestStatus.valueRequestStatus.LOADING viewModelScope.launch{valrequestResultasync{performSimulatedRequest()}.await()requestStatus.valueif(requestResult)RequestStatus.SUCCESSelseRequestStatus.FAIL}}/** * 使用 delay 方法模拟耗时操作用随机数模拟请求成功或失败 */privatesuspendfunperformSimulatedRequest()withContext(Dispatchers.IO){delay(500)valrandomRandom()returnwithContextrandom.nextBoolean()}}MainActivity中使用 Jetpack Compose将请求状态实时显示在界面上AndroidEntryPointclassMainActivity:ComponentActivity(){privatevalmainViewModel:MainViewModelbyviewModels()overridefunonCreate(savedInstanceState:Bundle?){super.onCreate(savedInstanceState)setContent{ComposeTheme{Surface(modifierModifier.fillMaxSize(),colorMaterialTheme.colorScheme.background){valrequestStatusStatemainViewModel.requestStatus.collectAsState()valrequestStatusbyrememberSaveable{requestStatusState}Text(textrequestStatus.name,colorColor.Red)}}}mainViewModel.simulateNetworkRequest()}}

相关新闻

FydeOS:国产ChromeOS替代方案深度解析与实战指南

FydeOS:国产ChromeOS替代方案深度解析与实战指南

1. FydeOS 是什么?ChromeOS 的国内替代方案深度解析第一次接触 FydeOS 是在三年前帮朋友的老旧笔记本寻找轻量级系统时。这台2015年的联想小新Air 13在Windows 10下已经卡得无法正常使用,但刷入FydeOS后竟然能流畅运行Android版微信和WPS,续航…

2026/7/16 10:02:23阅读更多 →
基于STC8H1K高级PWM的正交编码器测速与方向检测实践

基于STC8H1K高级PWM的正交编码器测速与方向检测实践

1. STC8H1K高级PWM与正交编码器基础 正交编码器在电机控制和位置检测中扮演着关键角色。这种传感器通过输出两路相位差90度的脉冲信号(A相和B相),不仅能测量转速,还能判断旋转方向。STC8H1K系列单片机内置的高级PWM模块&#xff0…

2026/7/16 10:02:23阅读更多 →
在MSYS2 CLANG64环境中配置与使用Clang/LLVM工具链

在MSYS2 CLANG64环境中配置与使用Clang/LLVM工具链

1. MSYS2 CLANG64环境简介 如果你在Windows平台上进行C/C开发,MSYS2绝对是个不可多得的好工具。它提供了多种终端环境,其中CLANG64环境特别适合需要LLVM工具链的开发者。我第一次接触这个环境时,就被它的便利性惊艳到了——再也不用折腾复杂的…

2026/7/16 10:02:23阅读更多 →
ChatGPT翻译提示词效能跃迁指南(附ISO/IEC标准对齐对照表)

ChatGPT翻译提示词效能跃迁指南(附ISO/IEC标准对齐对照表)

更多请点击: https://kaifayun.com 第一章:ChatGPT翻译提示词效能跃迁的底层逻辑 ChatGPT在翻译任务中的表现并非源于简单指令响应,而是提示词(Prompt)与模型内部语义对齐机制深度耦合的结果。当提示词精准激活模型的…

2026/7/16 11:17:52阅读更多 →
NiobeU4开发板LVGL移植与优化实战

NiobeU4开发板LVGL移植与优化实战

1. NiobeU4开发板与LVGL简介开鸿智谷NiobeU4是一款基于OpenHarmony系统的开发板,搭载高性能处理器和丰富的外设接口,特别适合物联网和嵌入式GUI开发。这块板子最吸引人的地方在于它原生支持OpenHarmony的轻量级内核LiteOS-M,同时提供了完整的…

2026/7/16 11:17:52阅读更多 →
怎样高效处理PDF文档:5个实用技巧掌握PDF补丁丁

怎样高效处理PDF文档:5个实用技巧掌握PDF补丁丁

怎样高效处理PDF文档:5个实用技巧掌握PDF补丁丁 【免费下载链接】PDFPatcher PDF补丁丁——PDF工具箱,可以编辑书签、剪裁旋转页面、解除限制、提取或合并文档,探查文档结构,提取图片、转成图片等等 项目地址: https://gitcode.…

2026/7/16 11:17:52阅读更多 →
Windows Storport Miniport驱动开发指南与性能优化

Windows Storport Miniport驱动开发指南与性能优化

1. Storport Miniport驱动开发概述在Windows存储驱动开发领域,Storport Miniport驱动扮演着关键角色。作为硬件厂商与Windows存储子系统之间的桥梁,这类驱动专门用于管理SCSI或NVMe接口的存储设备。与传统SCSI端口驱动相比,Storport架构提供了…

2026/7/16 11:17:52阅读更多 →
小红书数据采集终极指南:Python爬虫快速上手实战

小红书数据采集终极指南:Python爬虫快速上手实战

小红书数据采集终极指南:Python爬虫快速上手实战 【免费下载链接】xhs 基于小红书 Web 端进行的请求封装。https://reajason.github.io/xhs/ 项目地址: https://gitcode.com/gh_mirrors/xh/xhs 小红书作为国内领先的社交电商平台,蕴含着海量的用户…

2026/7/16 11:17:52阅读更多 →
CentOS 7服务器运维实战:从基础操作到性能调优

CentOS 7服务器运维实战:从基础操作到性能调优

1. CentOS 7基础操作环境概述作为Linux发行版中的"企业级常青树",CentOS 7凭借其出色的稳定性和长期支持周期(维护更新持续到2024年),至今仍是服务器环境的主流选择。与Ubuntu等面向个人用户的发行版不同,Ce…

2026/7/16 11:12:52阅读更多 →
VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异

VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异

VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异当你在VSCode中启动一个新的TypeScript项目时,第一个技术决策往往从安装方式开始。这个看似简单的选择——全局安装还是项目本地安装——实际上会深刻影响你的开发流程、团队协作和…

2026/7/16 8:28:11阅读更多 →
智慧树刷课插件:5分钟实现自动化学习的智能助手

智慧树刷课插件:5分钟实现自动化学习的智能助手

智慧树刷课插件:5分钟实现自动化学习的智能助手 【免费下载链接】zhihuishu 智慧树刷课插件,自动播放下一集、1.5倍速度、无声 项目地址: https://gitcode.com/gh_mirrors/zh/zhihuishu 智慧树刷课插件是一款专为智慧树在线教育平台设计的Chrome浏…

2026/7/16 6:53:04阅读更多 →
Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案

Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案

Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案 【免费下载链接】WorkshopDL WorkshopDL - The Best Steam Workshop Downloader 项目地址: https://gitcode.com/gh_mirrors/wo/WorkshopDL 你是否在GOG或Epic Games Store购买了心仪的游戏…

2026/7/15 10:54:00阅读更多 →
A--10 Codex Review与GitHub PR工作流实战指南:从代码审查到安全合并

A--10 Codex Review与GitHub PR工作流实战指南:从代码审查到安全合并

摘要:本文系统讲解如何利用Codex App的Review功能与GitHub PR工作流,实现从代码修改到安全合并的完整流程。涵盖Review面板深度使用、/review命令实战、GitHub Connector配置、PR描述撰写技巧,以及常见问题排查方法。通过多个实战案例和流程图,帮助开发者建立高效的AI辅助代…

2026/7/16 0:00:38阅读更多 →
遗传算法解5皇后问题:从Hello World到工业优化的进化实验室

遗传算法解5皇后问题:从Hello World到工业优化的进化实验室

1. 项目概述:为什么用遗传算法解5皇后问题,而不是直接回溯?我带过十几届算法课,也给不少初创团队做过AI架构咨询。每次讲到组合优化问题,学生和工程师的第一反应永远是“写个回溯试试”。这没错——55棋盘上找所有合法…

2026/7/16 0:00:38阅读更多 →
5.1V稳压管输出为何只有4.7V?工作电流与负载影响分析

5.1V稳压管输出为何只有4.7V?工作电流与负载影响分析

前几天调试一个简单的电源模块,用到了5.1V稳压管。电路接好,上电测试,万用表一量——输出居然只有4.7V。第一反应是稳压管坏了,换了一个新的,结果还是4.7V。这让我想起很多初学者都会遇到的困惑:明明标称5.…

2026/7/16 0:00:38阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/15 15:50:47阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/16 8:58:42阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/15 14:06:23阅读更多 →