没有合适的资源?快使用搜索试试~ 我知道了~
Kotlin协议详解-一文搞懂所有kotlin协议(珍藏版).pdf
需积分: 5 0 下载量 124 浏览量
2024-08-22
16:09:30
上传
评论 1
收藏 510KB PDF 举报
温馨提示
Kotlin协议详解-一文搞懂所有kotlin协议(珍藏版).pdf
资源推荐
资源详情
资源评论
/ 前言 /
为什么要写这篇文章
在学习和应用 Kotlin 协程过程中后有一些感受:
o 应用型的文章往往只是对照官网案例照猫画虎,几乎所有的文章都是先从 背景、优
势 、demo 基本应用案例,简单列举一下 launch 、async 、 Dispatchers 使用方
式,而缺少实战案例以及具体应用适用场景的分析,导致看了很多协程文章后,仍
然不会在项目中使用和解决实际碰到的问题.
o 原理型的文章通常会通过反编译协程源码来讲解状态机原理、CPS 转换、协程与线
程性能对比 等协程实现的核心概念和原理,从而深陷于复杂的源码之中。
o 在工作的项目中发现了许多协程 错用、滥用 地方.
为什么无法掌握协程
大多数文章会从如下几个方面进行讲解 :
• 协程的概念和作用:解释什么是协程以及它解决的问题。
• 状态机原理:阐述协程基于状态机的运行机制。
• 挂起与恢复:详细说明协程如何挂起和恢复执行。
• 调度器:介绍不同类型的调度器及其工作原理和适用场景。
• 协程的构建和启动:包括如何创建和启动协程。
• 上下文:讲解协程上下文的作用和管理。
• 与线程的关系:剖析协程与传统线程的联系和区别。
• 异常处理:说明协程中异常的传播和处理方式。
• 协程的优势和适用场景举例:通过具体案例展示协程的优点和适合应用的情况。
但是通常情况下我们了解到以上知识点以后,仍然无法熟练应用协程解决项目中实际的问
题。我仔细思考了一下,许多开发者不能很好的掌握和使用协程,主要原因如下 :
o 不清楚或者记不起来协程能够解决或简化项目中所遭遇的问题
o 缺乏对协程结构化并发设计思想思考
o 缺乏平滑的学习路线,一开始就直接学习 状态机原理、与线程关系和效率对比、协
程优势等理论知识,收益很小,容易被劝退 。
如何掌握协程 & 协程应用场景
通常需要重点关注如下知识点,就可以熟练掌握协程
1. 作用域(生命周期): 约束作用时间和范围 2. 切换与通讯 : 主协程 、子协程 互相切
换与通讯 3. 异常处理 :良好的异常处理机制
协程的应用场景是“以同步方式编写异步代码,解决回调(Callback)嵌套地狱问题”,然而通
常我们难以很好地理解、消化和吸收这句话。这句话可以解释为以下两点:
1. 解决多任务(同步/异步)执行时序问题 2. 解决 Callback 回调嵌套问题
/ 即刻开始 /
CoroutineScope 作用域 & Job
▪ CoroutineScope
CoroutineScope 是所有协程开始运行的 "容器", 它的主要作用是控制着协程运行的生命
周期,包括协程的创建、启动协程、取消、销毁。CoroutineScope 的取消也表示着在此作用
域内开启的协程将会被全部取消. CoroutineScope 内还可以创建 子 CoroutineScope , 不
同类型的作用域作用域代表着在此作用域内协程最大运行的时间不同。 例如 GlobalScope
表 示 协程的最大可运 行时 间 为 整 个 APP 的运 行 生 命 周 期 , Activity CoroutineScope
(lifecycleScope) 表示协程的最大可运行时间为 Activity 的生命周期, 协程伴随着
CoroutineScope 销毁而取消停止运行. Android 中常用的 CoroutineScope 类型和作用域:
▪ Job
Job 表示在一个 CoroutineScope 内开启的一个协程任务, Job 内可以开启多个子 Job ,
通常每开启一个协程任务后会返回一个 Job 对象,可以通过执行 Job.cancel() 方法取消协程
运行
viewLifecycleOwner.lifecycleScope.launch {
val job = launch {
// xxxx
}
val async = async {
// xxxx
}
async.cancel()
}
▪ CoroutineScope & Job
CoroutineScope 可以开启多个 Job , Job 内可以存在多个 CoroutineScope ,关系如下图
以 下 代 码 仅 是 为 了 表 达 两 者 之 间 的 关 系 , 不 推 荐 这 样 使 用 , 后 面 我 们 会 讲 到
supervisorScope 的使用场景.
viewLifecycleOwner.lifecycleScope.launch {
launch {
supervisorScope {
launch {
}
}
}
supervisorScope {
launch {
}
}
}
▪ coroutineScope vs supervisorScope (推荐使用)
viewLifecycleOwner.lifecycleScope.launch {
try {
coroutineScope {
val job1 = launch {
delay(2000)
// 如果抛出异常 , job1 停止执行 , job2 也会被取消,停止执行
throw NullPointerException()
}
val job2 = launch {
delay(2000)
println("println coroutineScope job 2")
}
// 如果执行 cancel ,job 1 , job 2 均取消
// cancel()
}
} catch (e: Throwable) {
// ignore
}
try {
supervisorScope {
val job1 = launch {
delay(2000)
// 如果抛出异常 , job1 停止执行 , job2 继续执行
throw NullPointerException()
}
val job2 = launch {
delay(2000)
println("println supervisorScope job 2")
}
// 如果执行 cancel ,job 1 , job 2 均取消
// cancel()
}
} catch (e: Throwable) {
// ignore
}
小结
coroutineScope 和 supervisorScope 实际业务开发中使用较少, 通常被使用在一个独立的
模块或其他服务请求任务关联后者影响较小时开启一个子作用域, 例如一个独立的服务请
求和子系统任务处理 。
o supervisorScope 在此作用域内开启的子协程发生异常以后, 则该作用域内的其他
兄弟协程不会受到影响,将正常执行.
o coroutineScope 在此作用域内开启的子协程发生异常以后, 该作用域内的所有协程
都将被取消.
o 在 coroutineScope 或 supervisorScope 内执行 cancel()方法取消协程, 作用域内部
的所有 Job 均会被取消.
▪ SupervisorJob vs Job
SupervisorJob 、 Job 可以在开启一个协程时设置任务类型,默认开启一个协程方式为
launch(){....} 内 部 实 现 为 Job(coroutineContext[Job]) , 也 可 以 通 过
launch(SupervisorJob(coroutineContext[Job])) { } ,
async(SupervisorJob(coroutineContext[Job])) { } 方式指定 Job 类型,它的主要作用异常发生
时,对父协程、兄弟协程影响.
SupervisorJob
SupervisorJob 下的 supervisorJob1 发 生 异 常 后 , SupervisorJob 下的 子 协 程
supervisorJob2 也会被取消, SupervisorJob 兄弟协程 job1 将正常执行并输出 "println
job1"
lifecycleScope.launch(handler) {
val job1 = launch {
delay(1000)
println("println job1")
}
剩余15页未读,继续阅读
资源评论
litterfinger
- 粉丝: 787
- 资源: 95
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功