Kotlin 协程作为 Android 异步编程的革命性解决方案,确实正在改变开发者处理并发任务的方式。以下是从入门到实战的系统性指南,帮助您掌握这项关键技术:
一、协程核心概念解析
-
轻量级线程:
- 协程比线程轻量 1000 倍以上(单个线程可运行数万个协程)
- 示例:启动 100,000 个协程仅需约 2.3MB 内存
repeat(100_000) { launch { delay(1000L) print(".") } }
-
结构化并发:
val parentJob = CoroutineScope(Dispatchers.Main).launch { val child1 = launch { /* 子任务1 */ } val child2 = launch { /* 子任务2 */ } } parentJob.cancel() // 自动取消所有子协程
-
挂起函数(Suspend Function):
suspend fun fetchUserData(): User { return withContext(Dispatchers.IO) { // 模拟网络请求 delay(1000) User(name = "John", age = 30) } }
二、Android 协程最佳实践
-
生命周期集成:
class MainActivity : AppCompatActivity() { private val scope = lifecycleScope override fun onCreate(savedInstanceState: Bundle?) { scope.launch { // 自动跟随生命周期取消 val data = fetchData() updateUI(data) } } }
-
多任务编排:
viewModelScope.launch { // 并发执行 val userDeferred = async { userRepository.getUser() } val postsDeferred = async { postRepository.getPosts() } // 等待所有结果 val (user, posts) = awaitAll(userDeferred, postsDeferred) // 合并结果 displayUserData(user, posts) }
-
异常处理模式:
val handler = CoroutineExceptionHandler { _, exception -> Log.e("Coroutine", "Caught $exception") } val job = CoroutineScope(Dispatchers.IO + handler).launch { // 可能抛出异常的代码 }
三、协程与 Android 架构组件集成
-
Room + 协程:
@Dao interface UserDao { @Query("SELECT * FROM users") suspend fun getAllUsers(): List<User> } viewModelScope.launch { val users = userDao.getAllUsers() _userList.value = users }
-
Retrofit + 协程:
interface ApiService { @GET("users/{id}") suspend fun getUser(@Path("id") userId: String): User } viewModelScope.launch { try { val user = apiService.getUser("123") _user.value = user } catch (e: IOException) { _error.value = "Network error" } }
四、性能优化技巧
-
调度器选择策略:
- Dispatchers.Main:UI 更新
- Dispatchers.Default:CPU 密集型计算
- Dispatchers.IO:磁盘/网络 I/O
- 自定义调度器:特殊线程池需求
-
协程取消模式:
val job = launch { try { repeat(1000) { i -> ensureActive() // 检查协程是否存活 // 长时间操作 } } finally { // 清理资源 } }
-
Flow 数据处理:
fun getLiveData(): Flow<List<Data>> = flow { while (true) { emit(repository.fetchLatest()) delay(5000) } }.flowOn(Dispatchers.IO)
五、调试与测试
-
**协程调试工具:
- 添加 VM 参数:
-Dkotlinx.coroutines.debug
- 输出包含协程信息:
[CoroutineName:background]
- 添加 VM 参数:
-
单元测试方案:
@Test fun testCoroutine() = runBlockingTest { val startTime = currentTime val deferred = async { delay(1000) "Result" } advanceTimeBy(1000) assertEquals("Result", deferred.await()) assertEquals(1000, currentTime - startTime) }
六、与 RxJava 对比
特性 | 协程 | RxJava |
---|---|---|
学习曲线 | 低(基于同步写法) | 高(响应式编程) |
内存占用 | 极低 | 中等 |
线程切换 | 更简洁 | 操作符组合 |
取消机制 | 结构化自动取消 | 需手动管理 |
适用场景 | 简单异步任务 | 复杂数据流处理 |
学习路线建议
- 官方文档:
kotlinlang.org/docs/coroutines
- Android 开发者指南:
developer.android.com/kotlin/coroutines
- 进阶书籍:《Kotlin Coroutines by Tutorials》
- 实战项目:实现一个包含网络请求、数据库操作、UI 更新的完整应用
掌握协程需要理解其非阻塞式挂起机制,建议从简单案例入手,逐步过渡到复杂场景。随着 Android Studio 对协程调试支持的不断完善(4.1+ 版本支持协程堆栈查看),开发体验将更加顺畅。