协程的基本使用

162 阅读4分钟

implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.2.0' //lifecycleScope implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0' //viewModeScope

启动协程的代码可以分为三部分:GlobalScope、launch、Dispatchers,它们分别对应:协程的作用域、构建器和调度器。

协程的作用域 GlobalScope 在应用范围内启动一个新协程,不会阻塞调用线程,协程的生命周期与应用程序一致。 表示一个不绑定任何Job的全局作用域,用于启动顶层协程,这些协程在整个应用程序生命周期中运行,不会提前取消(不存在Job)。 GlobalScope.launch { }

CoroutineScope 启动一个新的协程而不阻塞当前线程,并返回对协程的引用作为一个Job。 CoroutineScope会跟踪它使用 launch 或 async 创建的所有协程。您可以随时调用 scope.cancel() 以取消正在进行的工作(即正在运行的协程)。 在 Android 中,某些生命周期类提供自己的 CoroutineScope。例如,ViewModel 有 viewModelScope,Lifecycle 有 lifecycleScope。 创建自己的 CoroutineScope 以控制协程在应用的特定层中的生命周期如下: var job= CoroutineScope(Dispatchers.IO).launch { } job.cancel()

Job 是协程的句柄。使用 launch 或 async 创建的每个协程都会返回一个 Job 实例,该实例是相应协程的唯一标识并管理其生命周期

lifecycleScope 只能在Activity、Fragment中使用,会绑定Activity和Fragment的生命周期 lifecycleScope.launch {}

viewModelScope 是预定义的 CoroutineScope,只能在ViewModel中使用,绑定ViewModel的生命周期 viewModelScope.launch { }

构建器 launch 可启动新协程而不将结果返回给调用方。任何被视为“一劳永逸”的工作都可以使用 launch 来启动。

async会启动一个新的协程,并允许您使用一个名为 await 的挂起函数返回结果。如果您使用 async 从常规函数启动新协程,则能以静默方式丢弃异常。 通常,您应使用 launch 从常规函数启动新协程,因为常规函数无法调用 await。只有在另一个协程内时,或在挂起函数内且正在执行并行分解时,才使用 async。

调度器 Kotlin 提供了四个调度器,您可以使用它们来指定应在何处运行协程:

Dispatchers.Default默认调度器,非主线程。CPU密集型任务调度器,适合处理后台计算。通常处理一些单纯的计算任务,或者执行时间较短任务比如:Json的解析,数据计算等。 Dispatchers.MainUI调度器, Andorid 上的主线程。调度程序是单线程的,通常用于UI交互,刷新等。 Dispatchers.Unconfined一个不局限于任何特定线程的协程调度程序,即非受限调度器。子协程切换线程代码会运行在原来的线程上,协程在相应的挂起函数使用的任何线程中继续。 Dispatchers.IO调度器,非主线程,执行的线程是IO线程。适合执行IO相关操作,比如:网络处理,数据库操作,文件读写等。

withContext顶级函数 必须在协程或者suspend函数中调用,否则会报错。它必须显示指定代码块所运行的线程,它会阻塞当前上下文线程,有返回值,会返回代码块的最后一行的值。会自己切回线程 withContext(Dispatchers.IO)

启动模式含义说明 DEFAULT默认启动模式,立即根据它的上下文调度协程的执行是立即调度,不是立即执行,DEFAULT 是饿汉式启动,launch 调用后,会立即进入待调度状态,一旦调度器 OK 就可以开始执行。如果协程在执行前被取消,其将直接进入取消响应的状态。 LAZY懒启动模式,启动后并不会有任何调度行为,直到我们需要它执行的时候才会产生调度包括主动调用该协程的start、join或者await等函数时才会开始调度,如果调度前就被取消,协程将直接进入异常结束状态。 ATOMIC类似[DEFAULT],以一种不可取消的方式调度协程的执行虽然是立即调度,但其将调度和执行两个步骤合二为一了,就像它的名字一样,其保证调度和执行是原子操作,因此协程也一定会执行。 UNDISPATCHED类似[ATOMIC],立即执行协程,直到它在当前线程中的第一个挂起点。是立即执行,因此协程一定会执行。即使协程已经被取消,它也会开始执行,但不同之处在于它在同一个线程中开始执行。

suspend 标识有耗时操作。 有协程的方法都要加上suspend 。 协程 :线程框架 。 非阻塞式 : 可以自己切回来的切线程