协程

协程Coroutine可以理解成轻量的线程,运行在线程中的非阻塞的Task;协程不会与特定的线程绑定,它可以在不同的线程之间灵活切换。

相关API:

  • CoroutineContext

  • CancellationException

  • Continuation

  • Job

  • Deferred

  • CoroutineScope.async

  • CoroutineScope.launch

  • Channel

  • Flow

  • suspendCoroutineUninterceptedOrReturn

  • suspendCoroutine

  • suspendCancellableCoroutine

Android相关

CoroutineScope(携程作用域)

1
2
3
4
5
6
7
8
9
10
11
12
13
// Activity 中使用 lifecycleScope
lifecycleScope.launch {
// 协程代码
withContext(Dispatchers.IO) {
// IO 操作
}
// UI 操作
}

// ViewModel 中使用 viewModelScope
viewModelScope.launch {
// 协程代码
}

Dispatchers(调度器)

1
2
3
4
5
6
withContext(Dispatchers.IO) {
// IO 操作
}
withContext(Dispatchers.Main) {
// UI 操作
}

Job(任务)

1
2
3
4
5
6
val job = launch {
// 可取消的任务
deplay(1000) // 等待1秒
// 执行任务
}
job.cancel() // 取消任务

suspend

  • 标记函数为挂起函数
  • 可以调用其他挂起函数
  • 不会创建新的协程
  • 必须在协程或其他挂起函数中调用
1
2
3
4
suspend fun getData(): String {
delay(1000) // 挂起函数
return "data"
}

async & launch区别

都用来创建新携程,但有以下区别:

  • async 返回结果(Deferred)
  • launch 不返回结果(Job)
  • async 适合并行计算
  • launch 适合执行不需要返回值的任务
1
2
3
4
5
6
suspend fun loadDataParallel() = coroutineScope {
val data1 = async { getData1() } // 立即开始执行
val data2 = async { getData2() } // 立即开始执行
processData(data1.await(), data2.await()) //并行执行且有返回值
}

repeatOnLifecycle

这个API特别适合需要在应用前台时执行,后台时暂停的场景,比如实时数据更新、轮询操作等

1
2
3
4
5
6
7

lifecycleScope.launch {
lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
// 在 STARTED 状态下执行
}
}

参考