Kotlin:认识协程
前言
本文只是为了对Kotlin协程有个大体的概念,方便后面进行学习,后面会对协程各个知识点进行一个详细的学习记录
1、协程用来解决什么问题
- 处理耗时任务,这种任务常常会阻塞住主线程;
- 保证主线程安全,即确保安全地从主线程调用任何 suspend 函数。(suspend 是协程中的挂起函数)
本质上Kotlin协程就是作为在Kotlin语言上进行异步编程的解决方案,处理异步代码的方法
我们知道Handler、AsyncTask、RxJava等也能做到上面这两点,为什么要用协程呢?
2、协程的作用
协程最核心的作用就是最大程度简化并发异步任务,用同步代码写出异步效果
让我们的代码看起来更简洁,逻辑更清晰,避免地狱回调
地狱回调:Handler、AsyncTask、RxJava等都是通过回调实现主线程与耗时线程之前的切换,如果嵌套太多就会出现地狱回调,协程就是为了解决这个问题而出现的
3、协程与线程关系
- 协程基于线程,他是轻量级的线程
- 协程不能脱离与线程运行
- 协程虽然不能脱离线程,但是可以在不同线程中进行切换
协程并没有创造新的东西,只是将多线程开发变的更简单,原理依然是切换线程并回调到原本的线程
4、协程的特点
- 轻量:您可以在单个线程上运行多个协程,因为协程支持挂起,不会使正在运行协程的线程阻塞。挂起比阻塞节省内存,且支持多个并行操作。
- 内存泄漏更少:使用结构化并发机制在一个作用域内执行多项操作。
- 内置取消支持:取消操作会自动在运行中的整个协程层次结构内传播。
- Jetpack 集成:许多 Jetpack 库都包含提供全面协程支持的扩展。 ViewModelScope、LifecycleScope 等都是Jetpack对协程的支持
5、协程框架结构
kotlin的协程实现分为了两个层次:
- 基础设施层:标准库的协程API,主要对协程提供了概念和语义上最基本的支持
- 业务框架层 kotlin.coroutines:协程的上层框架支持,也是我们日常开发使用的库
项目要引入库对协程进行支持:
plugins {
id 'org.jetbrains.kotlin.android' version '1.7.20' apply false
}
dependencies {
//协程标准库
implementation 'org.jetbrains.kotlin:kotlin-stdlib:1.7.20'
//协程核心库
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2'
//协程Android支持库,提供安卓UI调度器
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2'
}
6、认识协程框架
①、挂起函数 Suspend
使用Suspend 关键字修饰的函数就是挂起函数
注意:挂起函数只能在协程或者其他挂起函数中调用
②、拦截器 ContinuationInterceptor
- 作用:线程切换
- 工作原理:拦截器返回一个代理Continuation对象给挂起函数,当挂起函数恢复的时候,恢复代理Continuation的resume函数,最后代理Continuation对象切换指定的线程在回调原始的Continuation对象
这个是协程内部处理的,一般我们用不到了解一下就好了
③、协程上下文 CoroutineContext
CoroutineContext即协程的上下文,是 Kotlin 协程的一个基本结构单元。巧妙的运用协程上下文是至关重要的,以此来实现正确的线程行为、生命周期、异常以及调试。
- Job: 控制协程的生命周期;
- CoroutineDispatcher: 向合适的线程分发任务;
- CoroutineName: 协程的名称,调试的时候很有用;
- CoroutineExceptionHandler: 处理未被捕捉的异常。
④、作用域 CoroutineScope
定义协程必须指定其作用域。作用域可以对协程进行追踪,即使协程被挂起也是如此。同调度程序 (Dispatcher) 不同,作用域并不运行协程,它只是确保您不会失去对协程的追踪。作用域会跟踪所有协程,同样它还可以取消由它所启动的所有协程。
作用域也是结构化并发机制的基础
我们可以自己进行自定义作用域,也可以使用Kotlin提供的常用作用域
Kotlin也提供了常用作用域:
作用域 | 说明 | 建议 |
---|---|---|
GlobalScope | 全局作用域,跟随整个进程的生命周期 | 不推荐使用 |
runBlocking | 主要用于测试,不用于日常开发,会阻塞线程 | 不推荐使用 |
MainScope | 跟Activity/Fragment生命周期挂钩 | 推荐使用 |
LifecycleOwner.lifecycleScope | 跟Lifecycle生命周期挂钩,由jetpack提供 | 推荐使用 |
ViewModel.viewModelScope | 跟ViewModel生命周期挂钩,由jetpack提供 | 推荐使用 |
⑤、调度器 CoroutineDispatcher
所有的协程都必须在调度器中执行,即使在主线程中运行也是一样的
Koltin提供了一下三种调度器:Dispatchers.Main、Dispatchers.IO、Dispatchers.Default,如果不指定默认是Defalut
调度器 | 应用线程 | 说明 | 使用场景 |
---|---|---|---|
Dispatchers.Default | 非主线程 | CPU密集型任务调度器 | 数组排序、Json解析、数据计算 |
Dispatchers.IO | 非主线程 | 磁盘和网络IO调度器 | 数据库、文件读写、网络处理 |
Dispatchers.Main | 主线程 | UI交互和轻量任务调度器 | 调用UI函数、更新LiveData |
Dispatchers.Unconfined | 任意线程 | 非受限调度器 | 子协程切换线程代码会运行在原来的线程上,协程在相应任何线程中继续 |
⑥、Job
每一个创建的协程都会返回一个Job实例,该实例是协程的唯一标识,负责管理协程的生命周期
Job的生命周期如下:
⑦、Flow
又称:冷数据流Flow
Flow可以让挂起函数异步的返回单个值,实现异步流
Flow是一种类似序列的冷流,flow构建器中的代码直到流被收集的时候才运行
⑧、Channel
又称:热数据通道Channel
Channel是一个并发安全的队列,他可以用来连接协程,实现不同协程的通信
⑨、Actor
actor 是一个实体,由一个协程、被限制并封装到这个协程中的状态以及一个与其它协程通讯的通道组成。
7、协程的构建器
协程的构建器常用有两个:作用域.launch 作用域.async
- CoroutineScope.launch():返回一个Job并且不附带返回值
- CoroutineScope.async():返回一个Deferred,Deferred是Job的一个子类
8、协程的启动模式
- CoroutineStart.DEFAULT:
协程创建后立即开始调度,在调度前如果协程被取消,就直接进入取消响应的状态,虽然是立即调度,但也有可能在执行前被取消。 - CoroutineStart.ATOMIC:
协程创建后立即开始调度,协程执行到第一个挂起点之前不响应取消,因此协程也一定会执行第一个挂起点前的逻辑。 - CoroutineStart.LAZY:
协程创建后等待调度,只有协程主动调用该协程的start、join或者await等函数时才会开始调度,如果调度前就被取消,就直接进入取消响应的状态。 - CoroutineStart.UNDISPATCHED:
协程创建后立即在当前函数调用栈中立即执行直到遇到第一个真正挂起的点,因此协程一定会执行
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgfkcbh
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13