1.什么是协程?
可以简单地将它理解成一种轻量级的线程。我们之前所学习的线程是非常重量级的,它需要依靠操作系统的调度才能实现不同线程之间的切换。而使用协程却可以仅在编程语言的层面就能实现不同协程之间的切换,从而大大提升了并发编程的运行效率。
为什么使用协程?
- 简洁性:协程使得异步代码看起来像同步代码,减少了回调地狱的问题。
- 轻量级:协程比线程更轻量,可以在同一线程中运行多个协程。
- 易于管理:协程可以通过结构化并发来管理生命周期,避免内存泄漏和资源浪费。
2.协程的基本用法
1.添加依赖:
如需在项目中使用协程,请将以下依赖项添加到应用的 build.gradle
文件中:
//kotlin协程核心库
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.9"
//协程Android支持库
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9"
2.协程作用域构建器
(1) GlobalScope.launch
GlobalScope.launch
是一种可以在任意地方调用的顶层协程构建器。使用 GlobalScope.launch
创建的协程是全局的,应用程序结束时这些协程也会随之结束。这种行为与线程类似,因为线程也没有层级概念,始终是顶层的。
示例代码:这里我们让协程挂起了1.5秒,但是线程却只阻塞了1秒
import kotlinx.coroutines.*
fun main() {
thread {
GlobalScope.launch {
println("codes run in coroutine scope")
delay(1500)
println("codes run in coroutine scope finished")
}
Thread.sleep(1000)
}.start()
}
运行结果
codes run in coroutine scope
在这个例子中,最后一条日志没有打印出来,因为协程还未执行完,应用程序就已经结束了。
注意事项
虽然 GlobalScope.launch
方便,但在实际项目中并不推荐使用。因为如果每次创建的都是顶层协程,当 Activity 关闭时,需要逐个调用所有已创建协程的 cancel()
方法,这样的代码维护起来非常困难。
来看一下示例代码中delay()函数和 Thread.sleep()方法的区别:
delay()函数是一个非阻塞式的挂起函数,它只会挂起当前协程,并不会影响其他协程的运行。
Thread.sleep()方法会阻塞当前线程,这样运行在该线程下的所有协程都会被阻塞。
(2) runBlocking
runBlocking
是一种可以在任意地方调用的构建器,它会阻塞当前线程,直到协程中的所有代码执行完毕。runBlocking
创建了一个协程