引入协程包
协程在Kotlin中是以第三方包的形式来使用。
目前位置,最新的协程库版本为: org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0
引用协程包
一般,为了方便,直接以如下形式引用协程包。
import kotlinx.coroutines.*
使用协程
runBlocking
kotlinx.coroutines.runBlocking
本质是一个函数。该函数传入一个闭包。
runBlocking 用于在线程中启动协程。
例:
fun main() = runBlocking {
delay(1000)
println("hello world")
}
// 或
fun main() {
runBlocking {
delay(1000)
println("hello world")
}
}
需要说明的是,runBlocking方法返回闭包最后一行的值。
有时候,runBlocking闭包最后一个行的类型不是Unit,那么runBlocking直接赋值给main就无法通过编译。解决的办法是给runBlocking的泛型类型指定返回类型为Unit。
例:给runBlocking指定返回的类型为Unit。否则无法通过编译。
fun main() = runBlocking<Unit> {
"return a String"
}
delay函数
协程的sleep函数。
例:循环打印
fun main() = runBlocking {
while (true) {
delay(1000)
println("hello world")
}
}
launch
launch 本质也是一个函数,接收闭包,返回 kotlinx.coroutines.Job
类型。该函数在协程中启动协程。
函数源码:
public fun CoroutineScope.launch(
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> Unit
): Job {
// ...
}
例:交替打印 hello 与 world。
// 此处一定要有Unit,launch返回Job类型。
// 如果不写Unit,编译起会认为runBlocking返回Job类型。从而无法直接赋值给main函数。
fun main() = runBlocking<Unit> {
launch {
while (true) {
println("hello")
delay(2000)
}
}
delay(1000)
launch {
while (true) {
println("world")
delay(2000)
}
}
}
Job类型
kotlinx.coroutines.Job
类型表示一个协程对象。可以类比于Thread对象。
Job类型的方法有:
- cancel()
- join()
例:job cancel 掉协程的运行。
fun main() = runBlocking<Unit> {
var job = launch {
while (true) {
delay(100)
println("hello world")
}
}
delay(800)
job.cancel()
}
async/await
这是两个函数,async用于启动异步协程任务。await得到异步协程任务的结果。