P7阿里大佬教你破解 Kotlin 协程(10) - Select 篇

安卓原生开发为何是初创企业的生存基础设施 安卓原生开发是移动应用开发的基础技术路径,指基于Android SDK、直接调用系统API构建高性能、高可控性客户端的能力。其核心原理在于绕过Web容器或跨端中间层,实现对硬件传感器、后台服务、离线存储及厂商推送等底层能力的稳定访问。相比H5、小程序或跨平台方案,原生开发在弱网适配、消息送达率、启动性能和隐私合规等方面具备不可替代的技术价值。典型应用场景包括社区团购实时订单同步、智能硬件蓝牙联动、车载Android Auto集成、金融类App安全保活等强交互、低延迟、高可靠性需求领域。对于资源有限的初创企业 阅读详情

破解 Kotlin 协程(10) - Select 篇

在这里插入图片描述

关键词:Kotlin 协程 Select 多路复用

Select 并不是什么新鲜概念,我们在 IO 多路复用的时候就见过它,在 Java NIO 里面也见过它。接下来给各位介绍的是 Kotlin 协程的 Select。

复用多个 await

我们前面已经接触了很多挂起函数,那么如果我有这样一个场景,两个 API 分别从网络和本地缓存获取数据,期望哪个先返回就先用哪个做展示:

fun CoroutineScope.getUserFromApi(login: String) = async(Dispatchers.IO){
    gitHubServiceApi.getUserSuspend(login)
}

fun CoroutineScope.getUserFromLocal(login:String) = async(Dispatchers.IO){
    File(localDir, login).takeIf { it.exists() }?.readText()?.let { gson.fromJson(it, User::class.java) }
}

不管先调用哪个 API 返回的 Deferred 的 await,都会被挂起,如果想要实现这一需求就要启动两个协程来调用 await,这样反而将问题复杂化了。

接下来我们用 select 来解决这个问题:

GlobalScope.launch {
    val localDeferred = getUserFromLocal(login)
    val remoteDeferred = getUserFromApi(login)

    val userResponse = select<Response<User?>> {
        localDeferred.onAwait { Response(it, true) }
        remoteDeferred.onAwait { Response(it, false) }
    }
    ...
}.join()

大家可以看到,我们没有直接调用 await,而是调用了 onAwait 在 select 当中注册了个回调,不管哪个先回调,select 立即返回对应回调中的结果。假设 localDeferred.onAwait 先返回,那么 userResponse 的值就是 Response(it, true),当然由于我们的本地缓存可能不存在,因此 select 的结果类型是 Response<User?>。

对于这个案例本身,如果先返回的是本地缓存,那么我们还需要获取网络结果来展示最新结果:

GlobalScope.launch {
    ...
    userResponse.value?.let { log(it) }
    userResponse.isLocal.takeIf { it }?.let {
        val userFromApi = remoteDeferred.await()
        cacheUser(login, userFromApi)
        log(userFromApi)
    }
}.join()

复用多个 Channel

对于多个 Channel 的情况,也比较类似:

val channels = List(10) { Channel<Int>() }

select<Int?> {
    channels.forEach { channel ->
        channel.onReceive { it }
        // OR
        channel.onReceiveOrNull { it }
    }
}

对于 onReceive,如果 Channel 被关闭,select 会直接抛出异常;而对于 onReceiveOrNull 如果遇到 Channel 被关闭的情况,it 的值就是 null。

SelectClause

我们怎么知道哪些事件可以被 select 呢?其实所有能够被 select 的事件都是 SelectClauseN 类型,包括:

  • SelectClause0:对应事件没有返回值,例如 join 没有返回值,对应的 onJoin 就是这个类型,使用时 onJoin 的参数是一个无参函数: select<Unit> { job.onJoin { log("Join resumed!") } }
  • SelectClause1:对应事件有返回值,前面的 onAwait 和 onReceive 都是此类情况。
  • SelectClause2:对应事件有返回值,此外还需要额外的一个参数,例如 Channel.onSend 有两个参数,第一个就是一个 Channel 数据类型的值,表示即将发送的值,第二个是发送成功时的回调: List(100) { element -> select<Unit> { channels.forEach { channel -> channel.onSend(element) { sentChannel -> log("sent on $sentChannel") } } } } 在消费者的消费效率较低时,数据能发给哪个就发给哪个进行处理,onSend 的第二个参数的参数是数据成功发送到的 Channel 对象。

因此如果大家想要确认挂起函数是否支持 select,只需要查看其是否存在对应的 SelectClauseN 即可。

小结

在协程当中,Select 的语义与 Java NIO 或者 Unix 的 IO 多路复用类似,它的存在使得我们可以轻松实现 1 拖 N,实现哪个先来就处理哪个。尽管 Select 和 Channel 比起标准库的协程 API 已经更接近业务开发了,不过个人认为它们仍属于相对底层的 API 封装,在实践当中多数情况下也可以使用 Flow API 来解决。

而这个 Flow API,完全就是响应式编程的协程版 API,我们简直可以照着 RxJava 来学习它,所以我们下一篇再见吧~~~

Kotlin 协程学习资料可以扫描下方二维码免费领取!

《史上最详Android版kotlin协程入门进阶实战》

第一章 Kotlin协程的基础介绍

            ● 协程是什么

            ● 什么是Job 、Deferred 、协程作用域

            ● Kotlin协程的基础用法

img

第二章 kotlin协程的关键知识点初步讲解

            ● 协程调度器

            ● 协程上下文

            ● 协程启动模式

            ● 协程作用域

            ● 挂起函数

img

第三章 kotlin协程的异常处理

            ● 协程异常的产生流程

            ● 协程的异常处理

img

第四章 kotlin协程在Android中的基础应用

            ● Android使用kotlin协程

            ● 在Activity与Framgent中使用协程

            ● ViewModel中使用协程

            ● 其他环境下使用协程

img

第五章 kotlin协程的网络请求封装

            ● 协程的常用环境

            ● 协程在网络请求下的封装及使用

            ● 高阶函数方式

            ● 多状态函数返回值方式
JetBrains 2025版:AI原生IDE的底层重构与开发范式升级 现代集成开发环境(IDE)已从代码编辑工具演进为AI驱动的智能开发操作系统。其核心原理在于将大模型推理能力深度嵌入平台内核,构建符号图谱索引、上下文感知引擎与多语言AI任务流水线。这种AI原生架构显著提升代码生成、智能调试、文档解析与资源管理的技术价值,广泛应用于Java微服务、PHP协程框架(如Webman)、Ruby元编程及.NET MAUI跨平台开发等复杂场景。尤其在JetBrains 2025系列中,IntelliJ Platform首次实现AI能力标准化抽象(ai-engine层)与硬件级授权验证 阅读详情

相关推荐

2026年AI编程工具选型决策地图:本地化、上下文与安全的工程实践指南

AI编程工具已从通用代码补全演进为深度耦合开发环境的技术基础设施。其核心原理在于对IDE抽象语法树(AST)、构建系统语义(如Maven依赖图、Cargo feature开关)及运行时上下文(如Spring Boot配置、Rust所有权模型)的精准建模;技术价值体现在将调试耗时压缩至秒级、降低跨语言/跨版本迁移门槛,并保障私有代码零出域;典型应用场景覆盖遗留系统理解、本地化实时纠错、结对式重构意图实现等真实工作流;而2026年工程落地的关键,正取决于能否在Ollama本地推理、GitHub Copilot

weixin_33725239的博客 400

2026年Java大厂面试深度解析与应对策略

Java作为企业级开发的核心语言,其技术栈深度与系统设计能力已成为大厂面试的关键考察点。从JVM内存模型到并发编程原理,再到分布式系统设计,现代Java工程师需要掌握底层机制与工程实践的平衡。以Spring框架为例,循环依赖解决和事务传播机制展现了框架设计的精妙之处;而在Redis等中间件应用中,Stream类型和持久化策略则体现了高性能系统的设计思想。面对2026年Java面试的'地狱级'难度,系统化的知识图谱构建和深度原理理解变得尤为重要,这不仅能提升面试通过率至47%,更能夯实工程师的核心竞争力。

weixin_34342992的博客 419

Android+PHP+MySQL登录注册系统实战指南

用户认证是移动应用开发的基础能力,其核心在于前后端安全、稳定、可调试的HTTP交互。理解HTTP请求响应机制、密码加盐哈希原理、SQL注入防护手段,是构建可靠登录系统的前提。技术价值体现在轻量可控——无需复杂框架即可实现跨安卓机型兼容、HTTPS通信、数据库防注入与字段级数据校验。典型应用场景包括教育类App、本地化工具软件等对高并发无要求但强调快速上线与自主运维的项目。本文聚焦Android原生客户端、PHP原生后端与MySQL数据库协同落地的真实链路,覆盖OkHttp网络调度、PDO预处理、utf8mb

weixin_34162228的博客 394

ChatGPT超级App:从对话模型到任务操作系统的演进

AI应用正经历从‘问答式交互’到‘任务式执行’的根本性范式迁移。其核心在于将自然语言指令转化为可分解、可调度、可验证的结构化任务流,依赖意图理解、工具调用、多模态执行与跨端协同四大技术支柱。这一转变使AI不再停留于信息检索或内容生成,而是深度嵌入工作流,实现端到端的结果交付——如自动订票、生成PPT、整理文件等真实场景。关键技术包括任务编排(Task Decomposition)、通用代理运行时(Agent Runtime)和网页意图驱动操作(Atlas),共同构成面向任务的操作系统雏形。本文聚焦该范式的架

afeyfre41671的博客 429

Lithe-IDEA:专为Java/Spring Boot深度优化的轻量级IDE内核

IDE(集成开发环境)是程序员的核心工作平台,其性能与专注度直接影响开发效率。基于IntelliJ Platform构建的现代IDE,虽功能强大,但多语言支持、冗余UI和后台服务常导致启动慢、内存高、学习成本上升。Lithe-IDEA并非简单裁剪,而是通过模块级重构、RoaringBitmap索引优化、原生UI直绘等底层技术,实现Java语义分析能力的极致保留与非必要功能的物理移除。它聚焦Spring Boot四层架构、Maven/Gradle构建、Actuator端点可视化等垂直场景,为金融政企、教学实践

weixin_34218579的博客 386

Kotlin与Java虚拟机五:Lambda 与高阶函数

Kotlin 的 Lambda 与高阶函数是其简洁语法的核心。函数可作为一等值,支持 it 隐式参数、尾随 Lambda 语法,并通过 inline 优化性能。集合操作如 filter、map、reduce 等均为扩展函数,支持链式调用,配合 asSequence() 可实现惰性求值。函数引用 :: 和 SAM 转换简化接口调用,闭包机制允许访问外部变量。这些特性使 Kotlin 代码更短、更清晰,且运行高效。

canfeit的专栏 284

工作中使用到的单词(软件开发)

1.エイリアス   alias 别名 powershell使用 get-help 命令时,会得到与此命令 相关(别名)的命令 2.プロキシ proxy 代 理 3.プロモート   promote 促进,提升   开发的系统新功能上线发布,有时会使用到这个词,比如 STプロモート 还有使用リリース这个词的。比如STリリース。个人认为两者含义相同。 4.見逃し み................................................................

sun0322 6万+

【信息科学与工程学】计算机科学与自动化——第一百九十八篇 高并发高可用的知识点01

以上补充约 110 行,涵盖分布式协调、服务网格细节、数据库高级特性、性能分析工具、混沌工程、安全渗透、合规审计、研发效能、新兴技术、架构模式、实用工具及经典论文。涵盖数据库索引与锁、NoSQL、前端性能、安全攻防、压测工具深入、监控深入、云原生存储、服务治理扩展、代码质量、DevOps 文化、行业标准、软技能及未来趋势。好的,继续补充更多高并发、高可用、高可靠的知识与技术,涵盖更深层的数据库内部机制、分布式事务、服务治理、运维自动化、安全与前沿技术等领域。

weixin_49199313的博客 736

Kotlin中级——callbackFlow

如下新增扩展函数,将监听过程转为Flow,可以流式处理,并绑定相关生命周期。转为Flow,并在Flow取消时同步取消监听。如下,是一个温度监听类,每隔1秒发送数据。若普通调用,需要自行注册和取消注册。

松仔Log的博客 165

【信息科学与工程学】计算机科学与自动化——第三百零四篇 高性能系统开发指南01

高并发:限流、熔断、降级高性能:红包拆分、多级缓存、大Key/热Key拆分、Pipeline、线程池、RocketMQ零丢失、幂等、分布式锁、集群缩容、分批入库海量数据处理:日志分表分片、跨表查询、冷热分层、大数据引擎服务器选型系统安全:网关安全、服务器安全、云存储安全、风控、监控、测试数据一致性:缓存与数据库一致性、大厂方案、蓝绿回滚、流量一致性、流程一致性项目与团队管理:流程问题、管理问题(风险、成本、人员、文档、培训)稳定性建设:上线三板斧、线上五步闭环、混沌工程、容量规划。

weixin_49199313的博客 251

Unity 开发Apple Vision Pro物体识别追踪ObjectTracking

当您在 visionOS 应用中实现对象跟踪时,您可以将现实世界中的物体无缝集成到人们的周围环境中,以增强他们的沉浸式体验。通过跟踪一个或多个物体的 3D 位置和方向,您的应用可以使用虚拟内容增强它们。您可以使用对象跟踪来提供与人周围环境中的对象的虚拟交互,例如:引导某人使用某件物品的功能、阅读其历史或了解其在周围环境中的行为。使用虚拟手册帮助人们解决家居用品和电器的问题。

Cool-浩 1186

KXBuild 实战,Windows 编译 Kotlin Multiplatform iOS,真机调试、打包 IPA

KMP 的 iOS 端只能在 macOS 上编?在 Windows 上也能跑,iosApp 的构建、安装和调试交给 KXBuild,Gradle 脚本和 iosApp 工程都不用改。Kotlin Multiplatform iOS 流程:体检、在 Config.xcconfig 填 Team ID 和 Bundle ID、连 iPhone 按 F5,在 VS Code 里同时给 Swift 和 Kotlin 打断点、看跨语言调用栈,Compose Multiplatform 同样适用,打出可上架 ipa。

2501_91373349的博客 244

开源光标主题实战:从Moshi Monsters到自定义指针的完整指南

光标主题是操作系统个性化的重要组成部分,它通过替换系统默认指针图标来改变视觉交互体验。其原理在于操作系统允许用户自定义指针资源文件,这些文件定义了不同状态下的光标图像。从技术价值看,一套设计良好的光标主题不仅能提升桌面美观度,还能增强用户的情感连接和操作愉悦感,是低成本高回报的数字幸福感提升方案。在应用场景上,无论是开发者、设计师还是普通用户,都可以通过更换光标主题来个性化工作环境。本文以热门的Moshi Monsters开源光标项目为例,深入解析了光标主题的设计逻辑、系统适配方案以及二次创作方法,涵盖了W

weixin_30879833的博客 572

Go1.27升后Errorf指针%w怎么改

Go1.27起printf vet会报告用%w包装*E(E已实现error);应改传值型error,并用errors.Is/As回归验收。

Amax3747的博客 498

ICT模拟零件测试方法--电容测试

通常,小到 100 pF 的电容需要补偿,因为夹具和系统的电容(20 到 50 pF)相对于被测设备的值是显著的。软件在需要补偿的电容测试中加入 comp 选项,而在不需要补偿的电容测试中加入 nocomp 选项。在调试期间,通过向电容语句添加 pc 选项验证您的电容测试。在测试单独的电容时,从测量结果中减去学到的值,然后与测试限制进行比较以决定通过或失败。请注意,如果用于需要补偿的电容测试上的感应总线使用了单独的探针,测量将无效。在测试电容时,应注意两个方面:电容的电阻元件,以及夹具和系统本身的电容。

可可南木的博客 1220

微信小程序地图开发避坑指南:腾讯地图API从配置到实战(附完整代码)

本文详细解析微信小程序中腾讯地图API的开发实践,从基础配置到高级功能实现,涵盖地图显示、地点搜索、路线规划等核心功能,并提供完整代码示例和常见问题解决方案,帮助开发者高效避坑。特别针对JavaScript SDK和map组件的使用进行了深度优化指导。

weixin_33725722的博客 486

kotlin常见面试题

Kotlin通过类型系统区分可空与不可空类型,编译期防止空指针异常。?.、?:(Elvis)、!!、lateinit、let等机制实现安全操作与延迟初始化。协程是轻量级、可挂起的计算,基于状态机实现,非线程,支持协作式调度。run、apply、let等作用域函数各有返回值与接收者引用差异。data class 自动生成equals、hashCode、toString、copy及解构。扩展函数为静态方法,不能访问私有成员,成员函数优先于扩展。inline内联消除高阶函数开销,crossinline限制非局部返

u012116089的博客 106

交通小白首投TRB就中Oral?我的完整时间线与避坑指南(附Editorial Manager实操截图)

本文详细解析了交通领域新手如何高效完成TRB国际会议投稿的全流程,从选题策略到投稿系统实操,再到评审过程解析和常见误区避坑指南。特别针对初次投稿者提供了实用建议,包括时间规划、选题考量、Editorial Manager系统操作技巧,以及如何应对评审意见。文章还分享了从录用到会议参与的关键步骤,帮助研究者提升投稿成功率。

weixin_27303545的博客 388

中文提问搜不到英文文档:查询翻译、多语言向量与语言感知融合怎么选,用跨语言 Recall@10 和单语回归验收

把决策压成几条。语料是单语言的,这套东西一个都不需要装。跨语言检索的全部成本都在「查询语言和文档语言不一致」这个前提上。跨语言查询是长尾、且现有系统在同语言上已经不错的,先做 LID 加分语言词法索引,不要先上翻译。前者是确定性的结构改动,不引入模型调用,能立刻消掉「中文查询打英文 BM25 返回空」这个静默退化;翻译是第二步。领域术语密集的场景,词表不是可选项。没有词表的查询翻译在技术文档上大概率是负收益:它把查询变得通顺,同时把唯一能匹配上的标识符弄丢了。

争者留其名 210

FPGA音频处理入门:手把手教你用Verilog实现I2S接收模块(附完整代码)

本文详细介绍了如何使用Verilog在FPGA上实现I2S接收模块,涵盖I2S协议原理、Verilog架构设计、完整代码实现及优化技巧。通过实战案例,帮助开发者快速掌握数字音频处理技术,适用于嵌入式音频系统开发。

weixin_30335575的博客 418

【QNX+Android虚拟化方案】136 - QNX 侧 Coredump 文件解析

【QNX+Android虚拟化方案】136 - QNX 侧 Coredump 文件解析

|~~~热爱生活、努力学习的小伙汁~~~| 1911

kotlin中的闭包特性

Kotlin 闭包允许函数捕获并修改外部作用域的变量,通过 Ref 包装类实现,比 Java 的“仅读取 final 变量”更灵活。闭包是函数式编程(如柯里化、高阶函数)的基础,但修改捕获变量不保证线程安全,需手动同步(如 Mutex、Atomic)。Java 限制修改捕获变量以避免并发陷阱,而 Kotlin 将选择权交予开发者:语法自由,责任自担。

YB1375的专栏 228

深度学习实战:基于YOLOv5/v8/v10的快递暴力分拣检测系统(完整版)

在电商物流高速发展的今天,快递包裹日均处理量已突破亿件级别。然而,快递分拣过程中的暴力抛扔行为不仅造成包裹损坏,更带来巨大的经济损失。据统计,每年因暴力分拣导致的快递破损投诉占总投诉量的30%以上。传统的人工监控方式存在疲劳、疏漏等问题,因此开发一套智能化的快递暴力分拣检测系统具有重要的现实意义。

YOLO 276

Gson + Kotlin 数据类的空安全陷阱:一次线上 NPE 崩溃的完整分析与修复

服务端返回 {"provinceName": null, ...}│▼Gson 反射赋值,绕过主构造函数和空检查│▼data.provinceName 实际是 null(但类型仍标记为非空 String)│▼主线程 lambda 拿着这个"假的非空值"传给非空参数│▼Intrinsics.checkNotNullParameter 抛出 NPE,主线程崩溃项目内容崩溃现象根本原因Gson 反射赋值绕过 Kotlin 构造函数与空检查,服务端返回显式null。

学习的最佳方式,就是把它写下来! 225

STM32F407中文手册

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

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

Android 开发入门实践(十):用 Kotlin 协程完成模拟加载、取消与异常处理

本文记录第118—125课对NewsApp的协程改造:从viewModelScope.launch启动协程,逐步加入delay模拟等待、suspend函数封装、withContext(Dispatchers.IO)切换线程并观察上下文恢复机制。通过日志验证withContext完成后恢复原执行上下文(非自动回主线程),纠正了初始理解偏差。引入Job管理任务,实现加载取消与重复点击防护,结合异常处理与状态管理,完成可观察、可中断的异步流程。

Easyhood的博客 404

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

IntelliJ IDEA 下载安装:写 Java 和 Kotlin 主流的开发工具

IntelliJ IDEA 是写 Java 和 Kotlin 最主流的开发工具。代码补全准、跳转快、重构稳,报错能直接给出改法。——个人写 Java 项目、学习、做课程作业,都能用完整的一套。

科小怪的博客 194
上一篇: 从阿里外包到华为OD的Android程序员
下一篇: 3月份的字节跳动面经
不秃头de程序猿
博客等级 码龄5年 4089粉丝 1478原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值