Kotlin协程 #
一、协程基础 #
1.1 什么是协程 #
协程是一种轻量级的线程,可以在代码中实现异步逻辑的同步写法,避免回调地狱。
1.2 添加依赖 #
kotlin
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3")
}
1.3 第一个协程 #
kotlin
fun main() = runBlocking {
launch {
delay(1000)
println("World!")
}
println("Hello,")
}
二、协程构建器 #
2.1 launch #
kotlin
val job = GlobalScope.launch {
delay(1000)
println("Hello")
}
job.join() // 等待协程完成
job.cancel() // 取消协程
2.2 async #
kotlin
val deferred = GlobalScope.async {
delay(1000)
"Result"
}
val result = deferred.await() // 获取结果
2.3 withContext #
kotlin
withContext(Dispatchers.IO) {
// 切换到IO线程执行
val data = fetchData()
data
}
2.4 runBlocking #
kotlin
runBlocking {
// 阻塞当前线程,直到协程完成
delay(1000)
}
三、调度器 #
3.1 调度器类型 #
kotlin
// Default:CPU密集型任务
launch(Dispatchers.Default) {
// 计算
}
// IO:IO密集型任务
launch(Dispatchers.IO) {
// 网络、文件操作
}
// Main:主线程(Android)
launch(Dispatchers.Main) {
// UI操作
}
// Unconfined:不指定线程
launch(Dispatchers.Unconfined) {
// 不推荐使用
}
3.2 切换调度器 #
kotlin
lifecycleScope.launch {
// 主线程
showLoading()
// 切换到IO线程
val data = withContext(Dispatchers.IO) {
fetchData()
}
// 回到主线程
showData(data)
}
四、协程作用域 #
4.1 作用域类型 #
kotlin
// GlobalScope:全局作用域(不推荐)
GlobalScope.launch { }
// CoroutineScope:自定义作用域
val scope = CoroutineScope(Dispatchers.Main)
scope.launch { }
// lifecycleScope:生命周期作用域(Android)
lifecycleScope.launch { }
// viewModelScope:ViewModel作用域(Android)
viewModelScope.launch { }
4.2 SupervisorJob #
kotlin
val scope = CoroutineScope(SupervisorJob() + Dispatchers.Main)
scope.launch {
// 子协程失败不会影响其他子协程
launch { }
launch { }
}
4.3 coroutineScope #
kotlin
suspend fun loadData() = coroutineScope {
launch {
// 子协程1
}
launch {
// 子协程2
}
}
五、协程取消 #
5.1 取消协程 #
kotlin
val job = scope.launch {
repeat(1000) {
delay(100)
println(it)
}
}
delay(500)
job.cancel()
job.join() // 或 job.cancelAndJoin()
5.2 检查取消状态 #
kotlin
val job = scope.launch {
repeat(1000) {
if (isActive) { // 检查是否活跃
// 执行任务
}
// 或使用ensureActive
ensureActive()
}
}
5.3 try-finally #
kotlin
val job = scope.launch {
try {
repeat(1000) {
delay(100)
println(it)
}
} finally {
// 清理资源
println("Cleanup")
}
}
job.cancelAndJoin()
5.4 不可取消的代码块 #
kotlin
val job = scope.launch {
try {
repeat(1000) {
delay(100)
println(it)
}
} finally {
withContext(NonCancellable) {
// 这里的代码不会被取消
delay(100)
println("Cleanup")
}
}
}
六、Flow #
6.1 创建Flow #
kotlin
fun getNumbers(): Flow<Int> = flow {
for (i in 1..10) {
delay(100)
emit(i)
}
}
6.2 收集Flow #
kotlin
lifecycleScope.launch {
getNumbers().collect { number ->
println(number)
}
}
6.3 Flow操作符 #
kotlin
lifecycleScope.launch {
getNumbers()
.map { it * 2 } // 映射
.filter { it > 5 } // 过滤
.take(3) // 取前3个
.collect { println(it) }
}
6.4 StateFlow #
kotlin
class MainViewModel : ViewModel() {
private val _state = MutableStateFlow<UiState>(UiState.Loading)
val state: StateFlow<UiState> = _state.asStateFlow()
fun loadData() {
viewModelScope.launch {
_state.value = UiState.Loading
try {
val data = repository.getData()
_state.value = UiState.Success(data)
} catch (e: Exception) {
_state.value = UiState.Error(e.message)
}
}
}
}
// 在Activity中观察
lifecycleScope.launch {
viewModel.state.collect { state ->
when (state) {
is UiState.Loading -> showLoading()
is UiState.Success -> showData(state.data)
is UiState.Error -> showError(state.message)
}
}
}
6.5 SharedFlow #
kotlin
class EventBus {
private val _events = MutableSharedFlow<Event>()
val events: SharedFlow<Event> = _events.asSharedFlow()
suspend fun send(event: Event) {
_events.emit(event)
}
}
// 发送事件
eventBus.send(Event.Message("Hello"))
// 接收事件
lifecycleScope.launch {
eventBus.events.collect { event ->
handleEvent(event)
}
}
七、异常处理 #
7.1 try-catch #
kotlin
scope.launch {
try {
val result = withContext(Dispatchers.IO) {
fetchData()
}
} catch (e: Exception) {
handleError(e)
}
}
7.2 CoroutineExceptionHandler #
kotlin
val handler = CoroutineExceptionHandler { _, exception ->
println("Caught $exception")
}
scope.launch(handler) {
throw RuntimeException("Error")
}
7.3 async异常 #
kotlin
scope.launch {
val deferred = async {
throw RuntimeException("Error")
}
try {
deferred.await()
} catch (e: Exception) {
println("Caught $e")
}
}
八、最佳实践 #
8.1 使用结构化并发 #
kotlin
// 推荐:使用作用域
lifecycleScope.launch {
// 自动管理生命周期
}
// 不推荐:使用GlobalScope
GlobalScope.launch {
// 不会自动取消
}
8.2 使用suspend函数 #
kotlin
suspend fun loadData(): Data {
return withContext(Dispatchers.IO) {
// 网络请求
fetchData()
}
}
8.3 避免阻塞 #
kotlin
// 不推荐
suspend fun bad() {
Thread.sleep(1000) // 阻塞线程
}
// 推荐
suspend fun good() {
delay(1000) // 不阻塞线程
}
九、总结 #
本章详细介绍了Kotlin协程:
- 协程的基本概念
- 协程构建器
- 调度器
- 协程作用域
- 协程取消
- Flow的使用
- 异常处理
- 最佳实践
协程是Kotlin最重要的特性之一,掌握协程对于Android开发至关重要。
最后更新:2026-03-26