2024年鸿蒙最全Kotlin协程:Flow基础原理_kotlin flow(2),HarmonyOS鸿蒙面试题解析

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!


img
img

既有适合小白学习的零基础资料,也有适合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行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值