深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上鸿蒙开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
}
// 检查上下文是否发生变化,如果变化,则抛出异常
checkContext(currentContext)
lastEmissionContext = currentContext
}
// 用于抛出异常
private fun exceptionTransparencyViolated(exception: DownstreamExceptionElement, value: Any?) {
error("""
Flow exception transparency is violated:
Previous 'emit' call has thrown exception ${exception.e}, but then emission attempt of value '$value' has been detected.
Emissions from 'catch' blocks are prohibited in order to avoid unspecified behaviour, 'Flow.catch' operator can be used instead.
For a more detailed explanation, please refer to Flow documentation.
""".trimIndent())
}
}
emit方法最终会调用emitFun方法方法,代码如下:
private val emitFun =
FlowCollector<Any?>::emit as Function3<FlowCollector<Any?>, Any?, Continuation, Any?>
emitFun是一个lambda表达式,它将只有一个参数的emit方法转换成三个参数的方法。emitFun方法在编译时会被编译器处理,反编译后的代码逻辑大致如下:
@Nullable
public final Object invoke(@NotNull FlowCollector p1, @Nullable Object p2, @NotNull Continuation continuation) {
InlineMarker.mark(0);
// 核心执行
Object var10000 = p1.emit(p2, continuation);
InlineMarker.mark(2);
InlineMarker.mark(1);
return var10000;
}
可以看到,emitFun方法内部会调用FlowCollector类对象的emit方法,同时传入value和continuation作为参数。
而这个FlowCollector类对象就是一开始的collect方法封装的匿名类对象,代码如下:
public suspend inline fun Flow.collect(crossinline action: suspend (value: T) -> Unit): Unit =
collect(object : FlowCollector {
override suspend fun emit(value: T) = action(value)
})
调用它的emit方法,会直接调用action的invoke方法,并传入发射的数据,流在这里被最终消费。
通过上面的分析,可以知道消费的过程是在emit方法中被调用的,如果在消费的过程,没有发生挂起,那么emit方法执行完毕后,会继续执行flow方法里剩下的代码,而如果在消费的过程中发生了挂起,情况会稍有不同。
### 4.消费过程中的挂起
如果消费过程中发生挂起,那么emit方法会返回一个`COROUTINE_SUSPENDED`对象,`suspendCoroutineUninterceptedOrReturn`方法在收到COROUTINE\_SUSPENDED对象后,会挂起当前协程。代码如下:
override suspend fun emit(value: T) {
// 获取当前suspend方法续体
return suspendCoroutineUninterceptedOrReturn sc@{ uCont ->
try {
// 调用重载的方法
emit(uCont, value)
} catch (e: Throwable) {
// 出现异常时,将异常封装成上下文,保存到lastEmissionContext
lastEmissionContext = DownstreamExceptionElement(e)
// 抛出异常
throw e
}
}
}
当消费过程执行完毕时,会通过传入的续体唤起外部协程恢复挂起状态。根据`emitFun`可以知道,这里传入的续体为this,也就是当前的`SafeCollector`类对象,代码如下:
emitFun(collector as FlowCollector<Any?>, value, this as Continuation)
恢复挂起需要调用续体的resumeWith方法,上面提到SafeCollector类继承自ContinuationImpl类,SafeCollector类中没有重写resumeWith方法,而ContinuationImpl类中也没有重写resumeWith方法,因此实际调用的是ContinuationImpl类的父类BaseContinuationImpl类的resumeWith方法。如下图所示:
![](https://img-blog.csdnimg.cn/img_convert/bbf07ef658c8a36d8f38bec47cee6001.png)
在[Kotlin协程:创建、启动、挂起、恢复]( )中提到过,调用BaseContinuationImpl类的resumeWith方法,内部会调用invokeSuspend方法,而SafeCollector类重写了invokeSuspend方法,代码如下:
override fun invokeSuspend(result: Result<Any?>): Any? {
// 尝试获取异常
result.onFailure { lastEmissionContext = DownstreamExceptionElement(it) }
// 如果没有异常,则恢复flow方法续体的执行
completion?.resumeWith(result as Result)
// 返回挂起标识,这里挂起的是消费过程
return COROUTINE_SUSPENDED
}
在invokeSuspend方法中,会调用resumeWith方法恢复生产过程——flow方法的执行,同时挂起消费过程的执行。全部过程如下图所示:
![](https://img-blog.csdnimg.cn/img_convert/29975ee75986e5abcb2224f354277a9f.png)
>
> 作者:李萧蝶
> 链接:https://juejin.cn/post/7137647612286468132
>
>
>
## 三、Kotlin学习资料
>
> 一. Kotlin入门教程指南
>
>
> 二. 高级Kotlin强化实战
>
>
> 三. Android版Kotlin协程入门进阶实战
>
>
>
### 《Kotlin入门教程指南》
#### **第一章 Kotlin 入门教程指南**
* 前言
![img](https://img-blog.csdnimg.cn/img_convert/3ff51b383a6231cca8f98a4a815c74a9.png)
#### **第二章 概述**
* 使用 Kotlin 进行服务器端开发
* 使用 Kotlin 进行 Android 开发
* Kotlin JavaScript 概述
* Kotlin/Native 用于原生开发
* 用于异步编程等场景的协程
* Kotlin 1.1 的新特性
* Kotlin 1.2 的新特性
* Kotlin 1.3 的新特性
![img](https://img-blog.csdnimg.cn/img_convert/8967c17a958efcbf2f0752536d160d5d.png)
#### **第三章 开始**
* 基本语法
* 习惯用法
* 编码规范
![img](https://img-blog.csdnimg.cn/img_convert/6f2ff3772284960a9a883aa0cdc41d01.png)
#### **第四章 基础**
* 基本类型
* 包
* 控制流:if、when、for、while
* 返回和跳转
![img](https://img-blog.csdnimg.cn/img_convert/839ed8e0daf14a934567b7bcdda606af.png)
#### **第五章 类与对象**
* 类与继承
* 属性与字段
* 接口
* 可见性修饰符
* 扩展
* 数据类
* 密封类
* 泛型
* 嵌套类与内部类
* 枚举类
* 对象表达式与对象声明
* Inline classes
* 委托
![img](https://img-blog.csdnimg.cn/img_convert/fa8d628bd6965061134b7af91656cca9.png)
#### **第六章 函数与 Lambda 表达式**
* 函数
* 高阶函数与 lambda 表达式
* 内联函数
![img](https://img-blog.csdnimg.cn/img_convert/c419719a0dd7e0c8f919366d4de28fe9.png)
#### **第七章 其他**
* 解构声明
* 集合:List、Set、Map
* 区间
* 类型的检查与转换“is”与“as”
* This 表达式
* 相等性
* 操作符重载
* 空安全
* 异常
* 注解
* 反射
* 类型安全的构建器
* 类型别名
* 多平台程序设计
* 关键字与操作符
![img](https://img-blog.csdnimg.cn/img_convert/89a2fa4143b1ee52e847d2f0bb1e55fa.png)
#### **第八章 Java 互操作与 JavaScript**
* 在 Kotlin 中调用 Java 代码
* Java 中调用 Kotlin
* JavaScript 动态类型
* Kotlin 中调用 JavaScript
* JavaScript 中调用 Kotlin
* JavaScript 模块
* JavaScript 反射
* JavaScript DCE
![img](https://img-blog.csdnimg.cn/img_convert/7158e0a6465dfa12306f5a12441eaec5.png)
#### **第九章 协程**
* 协程基础
* 取消与超时
* 通道 (实验性的)
* 组合挂起函数
* 协程上下文与调度器
* 异常处理
* select 表达式(实验性的)
* 共享的可变状态与并发
![img](https://img-blog.csdnimg.cn/img_convert/721e02ec1c3d5daeade692e6f0e12e3b.png)
#### **第十章 工具**
* 编写 Kotlin 代码文档
* Kotlin 注解处理
* 使用 Gradle
* 使用 Maven
* 使用 Ant
* Kotlin 与 OSGi
* 编译器插件
* 不同组件的稳定性
![img](https://img-blog.csdnimg.cn/img_convert/6bef50af94d70e5bf745b618decae131.png)
#### **第十一章 常见问题总结**
* FAQ
* 与 Java 语言比较
* 与 Scala 比较【官方已删除】
![img](https://img-blog.csdnimg.cn/img_convert/b435c5f51d5d414d97117d1a01d49519.png)
### **《**高级Kotlin强化实战**》**
#### **第一章 Kotlin 入门教程**
* Kotlin 概述
* Kotlin 与 Java 比较
* 巧用 Android Studio
* 认识 Kotlin 基本类型
* 走进 Kotlin 的数组
* 走进 Kotlin 的集合
* 完整代码
* 基础语法
![img](https://img-blog.csdnimg.cn/img_convert/dada14495ae74b64948e8eed682308fd.png)
#### **第二章 Kotlin 实战避坑指南**
* 方法入参是常量,不可修改
* 不要 Companion、INSTANCE?
* Java 重载,在 Kotlin 中怎么巧妙过渡一下?
* Kotlin 中的判空姿势
* Kotlin 复写 Java 父类中的方法
* Kotlin “狠”起来,连TODO都不放过!
* is、as` 中的坑
* Kotlin 中的 Property 的理解
* also 关键字
* takeIf 关键字
* 单例模式的写法
![img](https://img-blog.csdnimg.cn/img_convert/97894ffb8166dc33a159bcb9ea54dd17.png)
#### **第三章 项目实战《Kotlin Jetpack 实战》**
* 从一个膜拜大神的 Demo 开始
* Kotlin 写 Gradle 脚本是一种什么体验?
* Kotlin 编程的三重境界
* Kotlin 高阶函数
* Kotlin 泛型
* Kotlin 扩展
* Kotlin 委托
* 协程“不为人知”的调试技巧
* 图解协程:suspend
![img](https://img-blog.csdnimg.cn/img_convert/7aaecab89e33f7614792adaeb4ae79cb.png)
### **《**Android版Kotlin协程入门进阶实战**》**
#### **第一章 Kotlin协程的基础介绍**
* 协程是什么
* 什么是Job 、Deferred 、协程作用域
* Kotlin协程的基础用法
![img](https://img-blog.csdnimg.cn/img_convert/c3bbe2bc74a650690810f48ab3065bfe.png)
#### **第二章 kotlin协程的关键知识点初步讲解**
* 协程调度器
* 协程上下文
* 协程启动模式
* 协程作用域
* 挂起函数
![img](https://img-blog.csdnimg.cn/img_convert/dd5ec0e7cbeb06a4d35e2b3d0640cccc.png)
#### **第三章 kotlin协程的异常处理**
* 协程异常的产生流程
* 协程的异常处理
![img](https://img-blog.csdnimg.cn/img_convert/f95ad78b219cb326df42798062dc525f.png)
#### **第四章 kotlin协程在Android中的基础应用**
* Android使用kotlin协程
* 在Activity与Framgent中使用协程
* ViewModel中使用协程
* 其他环境下使用协程
![img](https://img-blog.csdnimg.cn/img_convert/b8c84b52dfb238bd0ecbe3452b34b5a3.png)
#### **第五章 kotlin协程的网络请求封装**
* 协程的常用环境
* 协程在网络请求下的封装及使用
* 高阶函数方式
* 多状态函数返回值方式
![img](https://img-blog.csdnimg.cn/img_convert/b98f3c365b73017f9467ca547bf75b27.png)
#### **第六章 深入kotlin协程原理(一)**
![img](https://img-blog.csdnimg.cn/img_convert/27fd3e2212db3ee183a8e863eefed6a0.png)
![img](https://img-blog.csdnimg.cn/img_convert/5c7f0689582453af6d614a0c7d54f07d.png)
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化的资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618636735)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
数返回值方式
![img](https://img-blog.csdnimg.cn/img_convert/b98f3c365b73017f9467ca547bf75b27.png)
#### **第六章 深入kotlin协程原理(一)**
[外链图片转存中...(img-HF9zVGwM-1715726778630)]
[外链图片转存中...(img-WGKin0Cq-1715726778630)]
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化的资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618636735)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**