枯燥的Kotlin协程三部曲(上)——概念启蒙篇(下)

简介: Kotlin 1.3 版本开始引入协程 Coroutine,简练的官方文档 和 网上一堆浅尝辄止的文章让我心里没底,不想止步于仅仅知道: ① Android中,Kotlin协程用于解决:处理耗时任务 和 保证主线程安全;② 利用Kotlin协程,可以用看起来:同步 的方式编写 异步 代码;③ 基础的API调用;

3、runOnUiThread


可以说是很无脑了,在子线程中想更新UI,直接写一个runOnUiThread{}包裹着UI更新相关的代码即可,示例如下:



点进源码康康:



噢,还挺简单:


Activity中定义了此函数,判断当前线程是否为主线程,不是 → Handler.post,是 → 直接执行UI更新。


回调确实是个好东西,但是多层次的回调嵌套,可能会形成 Callback Hell(回调地狱),比如现在有这样的逻辑:


访问百度 → 展示内容(UI) → 下载图标 → 显示图标(UI) → 生成缩略图 → 显示缩略图(UI) → 上传缩略图 → 界面更新(UI)


按照这样的逻辑,用runOnUiThread一把梭,伪代码如下:



常见的规避方法:把嵌套的层次移到外层空间,不使用匿名的回调函数,为每个回调函数命名。


4、RxJava


RxJava在 链式调用 的设计基础上,通过设置 不同的调度器,可以灵活地在 不同线程间切换 并执行对应的Task。


RxJava很强大,但因为较高的学习门槛,大多Android开发仔的认知还停留在:线程切换工具+操作符好用 的阶段。


有兴趣深入学习的RxJava的可以康康《RxJava 沉思录(一):你认为 RxJava 真的好用吗?》


这里只是展示效果,用RxJava写代码的效果,等我变强了,再回来完善这一块:



输出结果如下:



随心所欲,控制线程切换~


5、LiveData


LiveData 是Jetpack提供的一种响应式编程组件,可以包含任何类型的数据,并在数据发生变化时通知给观察者;由于它可以感知并遵循Activity、Fragment或Service等组件的生命周期,因此可以做到仅在组件处于声明周期的激活状态时才更新UI。一般是搭配 ViewModel 组件一起使用的。


MutableLiveData是一种可变的LiveData,提供了两种读数据的方法:


主线程中调用的setValue()在非主线程中调用的postValue()


使用时需导入依赖


implementation "androidx.lifecycle:lifecycle-runtime:2.2.0"


使用代码示例如下



6、Kotlin协程


使用Kotlin协程需要先添加 协程核心库和平台库 依赖(build.gradle中引入):


implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.7'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.7'


使用 withContext 函数可以切换到指定的线程,并在闭包内的逻辑执行结束后,自动把线程切换回上下文继续执行。把RxJava部分的示例改成Kotlin协程的形式,代码示例如下:



使用Kotlin协程后,代码量并没有减少,但是异步代码的编写却轻松多了,开始有一种「同步方式写异步代码」的味道了~


再简化下,把withContext 作为函数的返回值。



0x3、Kotlin中的协程到底是什么


协程


一种 非抢占式(协作式) 的 任务调度模式,程序可以 主动挂起或者恢复执行


与线程的关系


协程基于线程,但相对于线程轻量很多,可理解为在用户层模拟线程操作;每创建一个协程,都有一个内核态进程动态绑定,用户态下实现调度、切换,真正执行任务的还是内核线程。线程的上下文切换都需要内核参与,而协程的上下文切换,完全由用户去控制,避免了大量的中断参与,减少了线程上下文切换与调度消耗的资源。


根据 是否开辟相应的函数调用栈 又分成两类:


  • 有栈协程:有自己的调用栈,可在任意函数调用层级挂起,并转移调度权;


  • 无栈协程:没有自己的调用栈,挂起点的状态通过状态机或闭包等语法来实现;


Kotlin中的协程


"假"协程,Kotlin在语言级别并没有实现一种同步机制(锁),还是依靠Kotlin-JVM的提供的Java关键字(如synchronized),即锁的实现还是交给线程处理,因而Kotlin协程本质上只是一套基于原生Java Thread API 的封装。


只是这套API 隐藏了异步实现细节,让我们可以用如同 同步的写法来写异步操作 罢了。


参考文献:



相关文章
|
7月前
|
Java 数据库 Android开发
【专栏】Kotlin在Android开发中的多线程优化,包括线程池、协程的使用,任务分解、避免阻塞操作以及资源管理
【4月更文挑战第27天】本文探讨了Kotlin在Android开发中的多线程优化,包括线程池、协程的使用,任务分解、避免阻塞操作以及资源管理。通过案例分析展示了网络请求、图像处理和数据库操作的优化实践。同时,文章指出并发编程的挑战,如性能评估、调试及兼容性问题,并强调了多线程优化对提升应用性能的重要性。开发者应持续学习和探索新的优化策略,以适应移动应用市场的竞争需求。
180 5
|
7月前
|
传感器 Android开发 开发者
构建高效Android应用:Kotlin的协程与Flow
【4月更文挑战第26天】随着移动应用开发的不断进步,开发者寻求更简洁高效的编码方式以应对复杂多变的业务需求。在众多技术方案中,Kotlin语言凭借其简洁性和强大的功能库逐渐成为Android开发的主流选择。特别是Kotlin的协程和Flow这两个特性,它们为处理异步任务和数据流提供了强大而灵活的工具。本文将深入探讨如何通过Kotlin协程和Flow来优化Android应用性能,实现更加流畅的用户体验,并展示在实际开发中的应用实例。
|
7月前
|
移动开发 Java Android开发
构建高效Android应用:Kotlin与协程的完美融合
【2月更文挑战第25天】 在移动开发领域,性能优化和应用响应性的提升是永恒的追求。随着Android Jetpack组件库的不断丰富,Kotlin语言已经成为Android开发的首选。而Kotlin协程作为一种新的并发处理方案,它以轻量级线程的形式,为开发者提供了简洁高效的异步编程手段。本文将深入探讨Kotlin协程在Android应用中的实践运用,以及如何通过这种技术改善用户界面的流畅度和后台任务的处理能力,进而构建出更高效、更稳定的Android应用。
|
7月前
|
安全 Android开发 开发者
构建高效Android应用:Kotlin与协程的完美结合
【2月更文挑战第30天】在移动开发领域,性能优化和流畅的用户体验是关键。本文深入探讨了如何通过结合Kotlin语言和协程技术来提升Android应用的性能和响应能力。我们将分析Kotlin的优势,介绍协程的基本概念,并通过实际案例展示如何在应用中实现协程以简化异步编程,从而提供更加高效的解决方案。
|
4月前
|
Go 调度 开发者
[go 面试] 深入理解进程、线程和协程的概念及区别
[go 面试] 深入理解进程、线程和协程的概念及区别
|
6月前
|
分布式计算 JavaScript 前端开发
多线程、多进程、协程的概念、区别与联系
多线程、多进程、协程的概念、区别与联系
98 1
|
2月前
|
JSON 调度 数据库
Android面试之5个Kotlin深度面试题:协程、密封类和高阶函数
本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点。文章详细解析了Kotlin中的协程、扩展函数、高阶函数、密封类及`inline`和`reified`关键字在Android开发中的应用,帮助读者更好地理解和使用这些特性。
30 1
|
3月前
|
数据采集 消息中间件 并行计算
进程、线程与协程:并发执行的三种重要概念与应用
进程、线程与协程:并发执行的三种重要概念与应用
63 0
|
4月前
|
调度 开发者 UED
Kotlin 中的协程是什么?
【8月更文挑战第31天】
278 0
|
6月前
|
存储 Java 调度
Android面试题之Kotlin 协程的挂起、执行和恢复过程
了解Kotlin协程的挂起、执行和恢复机制。挂起时,状态和上下文(局部变量、调用栈、调度器等)被保存;挂起点通过`Continuation`对象处理,释放线程控制权。当恢复条件满足,调度器重新分配线程,调用`resumeWith`恢复执行。关注公众号“AntDream”获取更多并发知识。
134 2