跳转到内容
主菜单
主菜单
移至侧栏
隐藏
导航
首页
最近更改
随机页面
MediaWiki帮助
代码酷
搜索
搜索
中文(中国大陆)
外观
创建账号
登录
个人工具
创建账号
登录
未登录编辑者的页面
了解详情
贡献
讨论
编辑“︁
Kotlin协程
”︁
页面
讨论
大陆简体
阅读
编辑
编辑源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
编辑
编辑源代码
查看历史
常规
链入页面
相关更改
特殊页面
页面信息
外观
移至侧栏
隐藏
您的更改会在有权核准的用户核准后向读者展示。
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
# Kotlin协程 Kotlin协程是Kotlin语言提供的一种轻量级并发编程解决方案,它简化了异步编程和并发操作的管理。协程允许开发者以顺序的方式编写异步代码,同时保持高效的资源利用。 ## 概述 Kotlin协程基于以下核心概念: * **轻量级线程**:比传统线程更高效,可创建数千个协程而不会导致性能问题 * **挂起函数**:使用`suspend`关键字标记,可以在不阻塞线程的情况下暂停执行 * **结构化并发**:提供明确的生命周期管理和错误传播机制 * **协程上下文**:定义协程执行的环境,包括调度器、异常处理器等 ## 基本用法 ### 启动协程 Kotlin提供了几种启动协程的方式: <syntaxhighlight lang="kotlin"> // 使用GlobalScope启动协程(不推荐在生产代码中使用) GlobalScope.launch { // 协程体 fetchData() } // 推荐的方式:使用CoroutineScope val scope = CoroutineScope(Dispatchers.Main) scope.launch { // 在主线程执行的协程 val result = fetchData() updateUI(result) } </syntaxhighlight> ### 挂起函数 挂起函数是协程的核心构建块: <syntaxhighlight lang="kotlin"> suspend fun fetchData(): String { return withContext(Dispatchers.IO) { // 模拟网络请求 delay(1000) // 非阻塞延迟 "数据加载完成" } } </syntaxhighlight> ## 协程调度器 Kotlin提供了几种预定义的调度器: * **Dispatchers.Main**:Android主线程 * **Dispatchers.IO**:适合I/O密集型操作 * **Dispatchers.Default**:适合CPU密集型操作 * **Dispatchers.Unconfined**:不限定特定线程 ## 结构化并发 Kotlin协程通过结构化并发管理协程生命周期: <syntaxhighlight lang="kotlin"> class MyActivity : AppCompatActivity(), CoroutineScope by MainScope() { override fun onDestroy() { super.onDestroy() cancel() // 取消所有子协程 } fun loadData() { launch { try { val data = fetchData() showData(data) } catch (e: Exception) { showError(e) } } } } </syntaxhighlight> ## 协程与Android应用 在Android开发中,协程常用于以下场景: 1. **网络请求**:替代回调或RxJava 2. **数据库操作**:Room数据库支持协程 3. **UI更新**:在主线程安全地更新UI 4. **并行任务**:使用`async/await`模式 示例:结合ViewModel使用协程 <syntaxhighlight lang="kotlin"> class MyViewModel : ViewModel() { private val repository = DataRepository() val data = liveData { emit(Resource.loading()) try { emit(Resource.success(repository.fetchData())) } catch (e: Exception) { emit(Resource.error(e)) } } } </syntaxhighlight> ## 高级特性 ### 协程上下文 可以自定义协程上下文: <syntaxhighlight lang="kotlin"> val customDispatcher = Executors.newFixedThreadPool(4).asCoroutineDispatcher() val exceptionHandler = CoroutineExceptionHandler { _, exception -> println("协程异常: $exception") } val customContext = customDispatcher + exceptionHandler </syntaxhighlight> ### 通道(Channel) 协程间的通信机制: <syntaxhighlight lang="kotlin"> val channel = Channel<Int>() launch { for (x in 1..5) channel.send(x) channel.close() } launch { for (y in channel) println(y) } </syntaxhighlight> ### 流(Flow) 异步数据流处理: <syntaxhighlight lang="kotlin"> fun fetchItems(): Flow<Item> = flow { for (i in 1..10) { delay(100) emit(Item(i)) } } launch { fetchItems() .filter { it.id % 2 == 0 } .collect { item -> println(item) } } </syntaxhighlight> ## 性能优势 Kotlin协程相比传统线程的优势: * **内存占用低**:协程栈可复用,创建成本低 * **调度高效**:协程切换不涉及操作系统线程切换 * **资源可控**:通过调度器限制并发数量 * **错误处理**:结构化并发简化错误传播 ## 常见问题 ### 协程与线程的区别 | 特性 | 协程 | 线程 | |------|------|------| | 创建成本 | 低 | 高 | | 切换开销 | 小 | 大 | | 并发数量 | 数千 | 数百 | | 调度方式 | 协作式 | 抢占式 | | 内存占用 | 几十KB | 几MB | ### 协程泄漏 协程泄漏常见原因: * 忘记取消不再需要的协程 * 在已销毁的Activity/Fragment中继续运行协程 * 持有外部对象的强引用 解决方案: * 使用结构化并发 * 实现CoroutineScope接口 * 使用viewModelScope或lifecycleScope ## 最佳实践 1. **避免GlobalScope**:使用自定义作用域 2. **正确处理异常**:使用CoroutineExceptionHandler 3. **合理选择调度器**:根据任务类型选择 4. **测试协程代码**:使用TestCoroutineDispatcher 5. **结合LiveData使用**:使用liveData构建器 ## 相关库 * **kotlinx.coroutines**:官方协程库 * **Room**:支持协程的数据库库 * **Retrofit**:支持协程的网络库 * **WorkManager**:支持协程的后台任务调度 ## 参见 * [[Android (Kotlin)]] * [[异步编程]] * [[响应式编程]] * [[线程与并发]] * [[Kotlin Flow]] [[Category:Kotlin]] [[Category:Android开发]] [[Category:并发编程]] [[Category:编程概念]]
摘要:
请注意,所有对代码酷的贡献均被视为依照知识共享署名-非商业性使用-相同方式共享发表(详情请见
代码酷:著作权
)。如果您不希望您的文字作品被随意编辑和分发传播,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)