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

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

6、并发 & 并行


上面提到一个名词 并发 (Concurrency),指的是:


同一时刻只有一条指令执行,但多个进程指令被快速地 轮换执行,使得在宏观上有同时执行的效果,微观上并不是同时执行,只是把CPU时间分成若干段,使得多个进程快速交替地执行,存在于单核或多核CPU系统中。


而另一个容易混淆的名词 并行 (Parallel) 则是:


同一时刻,有多条指令在多个处理器上同时执行,从微观和宏观上看,都是一起执行的,存在于多核CPU系统中。


7、协作式 & 抢夺式


单核CPU,同一时刻只有一个进程在执行,这么多进程,CPU的时间片该如何分配呢?

协作式多任务


早期的操作系统采用的就是协作时多任务,即:


由进程主动让出执行权,如当前进程需等待IO操作,主动让出CPU,由系统调度下一个进程。


每个进程都循规蹈矩,该让出CPU就让出CPU,是挺和谐的,但也存在一个隐患:


单个进程可以完全霸占CPU


计算机中的进程良莠不齐,先不说那种居心叵测的进程了,如果是健壮性比较差的进程,运行中途发生了死循环、死锁等,会导致整个系统陷入瘫痪!在这种鱼龙混杂的大环境下,把执行权托付给进程自身,肯定是不符合基础国情,由操作系统扛大旗的 抢占式多任务 横空出世~


抢占式多任务


由操作系统决定执行权,操作系统具有从任何一个进程取走控制权和使另一个进程获得控制权的能力。


系统公平合理地为每个进程分配时间片,进程用完就休眠,甚至时间片没用完,但有更紧急的事件要优先执行,也会强制让进程休眠。有了进程设计的经验,线程也做成了抢占式多任务,但也带来了新的——线程安全问题


8、线程安全问题


进程在执行过程中拥有独立的内存单元,而多个线程共享这个内存,可能存在这样一种情况:


假设有一个变量a = 10,它可以被线程t1和t2共享访问,两个线程都会对i值进行写入,假设在单核CPU上运行此程序,系统需要给两个线程都分配CPU时间片:


  • 1.t1从内存中读取了a的值为10,它把a的值+1,准备把11这个新值写入内存中,此时时间片耗尽;


  • 2.系统执行了线程调度,t1的执行现场被保存,t2获得执行,它也去读a的值,此时a的值仍为10,+1,然后把11写入内存中;


  • 3.t1再次被调度,此时它也把11写入内存中。


程序的执行结果和我们的预期不符,a的值应该为12而不是11,这就是线程调度不可预测性引起的 线程同步安全问题


解决方法


系列化访问临界资源,同一时刻,只能有一个线程访问临界资源,也称 同步互斥访问,通常的操作就是 加锁(同步锁),当线程访问临界资源时需要获得这个锁,其他线程无法访问,只能 等待(堵塞),等这个线程使用完释放锁,供其他线程继续访问。


前置概念相关的东西就说这么多,相信会对你接下来学习Kotlin协程大有裨益。


0x2、单线程的Android GUI系统


是的,Android GUI 被设计成单线程了,你可能会问:为啥不采用性能更高的多线程?


答:如果设计成多线程,多个线程同时对一个UI控件进行更新,容易发生 线程同步安全问题;最简单的解决方式:加锁,但这意味着更多的耗时和UI更新效率的降低,而且还有死锁等诸多问题要解决;多线程模型带来的复杂度成本,远远超出它能提供的性能优势成本。这也是大部分GUI系统都是单线程模型的原因。


Android要求:在主线程(UI线程)更新UI,注意是 → 要求建议,不是规定,规定底线是:


只有创建这个view的线程才能操作这个view


所以,你在子线程中更新子线程创建的UI也是可以的,不过不建议这么做,建议:


在子线程中完成耗时操作,然后通过Handler发送消息,通知UI线程更新UI。


Tips:关于Handler更多的内容可移步至:《换个姿势,带着问题看Handler》


接着说下,Android异步更新UI的写法都有哪些~


1、Handler


主线程中实例化一个Handler对象,在子线程需要更新UI的地方,通过Handler对象的post(runnable)或其他函数,往主线程的消息队列发送消息,等待调度器调度,分发给对应的Handler完成UI更新,写法示例如下:



利用 lambda表达式 + Kotlin语法糖thread { } 可对上述代码进行简化:



还有另外一种常见的写法:自定义一个静态内部类Handler,把UI更新操作统一放到这里,根据msg.what进行区分。


2、AsyncTask


AsyncTask是Android提供的一个轻量级的用于处理异步任务的类(封装Handler+Thread),使用代码示例如下:



相比起手写Handler简单了一些,只需要继承AsyncTask,然后就是填空题(按需重写函数):


  • onPreExecute():异步操作开始,可以做一些UI的初始化操作;


  • doInBackground():执行异步操作,可调用publishProgress()触发onProgressUpdate()进度更新;


  • onProgressUpdate():根据进度更新UI;


  • onPostExecute():异步操作完成,更新UI;


但也存在以下局限性:


① AsyncTask类需在主线程中加载;


② AsyncTask对象需在主线程中创建;


③ execute()必须在主线程中调用,且一个AsyncTask对象只能调用一次此方法;


④ 需要为每一种任务类型创建一个特定子类,同时为了访问UI方便,经常定义为Activity的内部类,耦合严重。


可以通过 函数转换为回调的方式 来解耦,抽取后的自定义AsyncTask类如下:



调用也很简单,按需重写对应函数即可:



解耦后灵活多了,外部调用逻辑内部异步逻辑 的分离开来了,但依旧存在问题,如异常处理、任务取消等。


相关文章
|
5天前
|
传感器 Android开发 开发者
构建高效Android应用:Kotlin的协程与Flow
【4月更文挑战第26天】随着移动应用开发的不断进步,开发者寻求更简洁高效的编码方式以应对复杂多变的业务需求。在众多技术方案中,Kotlin语言凭借其简洁性和强大的功能库逐渐成为Android开发的主流选择。特别是Kotlin的协程和Flow这两个特性,它们为处理异步任务和数据流提供了强大而灵活的工具。本文将深入探讨如何通过Kotlin协程和Flow来优化Android应用性能,实现更加流畅的用户体验,并展示在实际开发中的应用实例。
|
2月前
|
安全 Android开发 开发者
构建高效Android应用:Kotlin与协程的完美结合
【2月更文挑战第30天】在移动开发领域,性能优化和流畅的用户体验是关键。本文深入探讨了如何通过结合Kotlin语言和协程技术来提升Android应用的性能和响应能力。我们将分析Kotlin的优势,介绍协程的基本概念,并通过实际案例展示如何在应用中实现协程以简化异步编程,从而提供更加高效的解决方案。
|
2月前
|
移动开发 Java Android开发
构建高效Android应用:Kotlin与协程的完美融合
【2月更文挑战第25天】 在移动开发领域,性能优化和应用响应性的提升是永恒的追求。随着Android Jetpack组件库的不断丰富,Kotlin语言已经成为Android开发的首选。而Kotlin协程作为一种新的并发处理方案,它以轻量级线程的形式,为开发者提供了简洁高效的异步编程手段。本文将深入探讨Kotlin协程在Android应用中的实践运用,以及如何通过这种技术改善用户界面的流畅度和后台任务的处理能力,进而构建出更高效、更稳定的Android应用。
|
2天前
|
算法 安全 Android开发
深入理解操作系统的内存管理机制构建高效Android应用:Kotlin的协程优势
【4月更文挑战第30天】 在现代计算机系统中,操作系统的内存管理是确保系统高效、稳定运行的关键。本文将探讨操作系统内存管理的核心技术,包括内存分配、虚拟内存、分页和分段等概念,以及它们是如何协同工作以提高内存利用率和系统性能的。通过对这些技术的详细分析,我们可以更好地理解操作系统背后的原理,并评估不同内存管理策略对系统行为的影响。 【4月更文挑战第30天】 在移动开发领域,尤其是针对Android平台,性能优化和流畅的用户体验始终是开发者追求的核心目标。随着Kotlin语言的普及,协程作为其在异步编程领域的杀手锏特性,已经逐渐成为提高应用性能和简化代码结构的重要工具。本文将深入探讨Kotli
|
3天前
|
数据处理 调度 Android开发
构建高效Android应用:探究Kotlin的协程优势
【4月更文挑战第28天】 随着移动应用开发日趋复杂,传统的线程和异步处理模型在处理并发任务时显得笨重且易出错。本文深入分析了Kotlin协程作为一种轻量级线程管理方案的优势,探讨了其在Android应用中实现流畅用户界面和提升性能的潜力。通过对协程原理的剖析以及与现有技术的比较,揭示了如何利用协程优化应用结构、简化代码逻辑,并提高应用的响应性和可维护性。
|
18天前
|
数据库 Android开发 UED
构建高效Android应用:Kotlin与协程的完美结合
【4月更文挑战第14天】在现代Android开发中,Kotlin语言和协程已经成为提升应用性能和简化异步编程的关键技术。本文深入探讨了如何通过结合Kotlin的简洁语法和协程的轻量级并发能力来构建一个高效的Android应用。我们将分析协程的核心原理,展示其在处理网络请求、数据库操作和UI线程中的实际应用,并提供优化策略以确保流畅的用户体验和低资源消耗。
20 4
|
2月前
|
移动开发 调度 Android开发
构建高效Android应用:Kotlin与协程的完美结合
【2月更文挑战第21天】随着移动开发技术的不断进步,Android平台正寻求更高效、更简洁的编程解决方案。Kotlin作为一种现代编程语言,以其简洁性和对函数式编程的支持赢得了开发者的青睐。而协程作为处理异步任务的强大工具,在提升应用性能方面显示出巨大潜力。本文将深入探讨Kotlin语言和协程技术如何相辅相成,帮助开发者构建更加流畅和高效的Android应用。
|
2月前
|
API 数据库 Android开发
构建高效安卓应用:Kotlin与协程的完美融合
【2月更文挑战第20天】在移动开发领域,性能优化和资源管理始终是开发者关注的焦点。随着Kotlin语言在Android平台的普及,协程作为其核心特性之一,提供了一种全新的异步编程范式。本文将深入探讨如何通过Kotlin协程提升安卓应用的性能,减少内存消耗,并实现流畅的用户体验。我们将分析协程的原理,展示其在实际应用中的效能,并提供实践指南,帮助开发者掌握这一强有力的工具。
15 0
|
2月前
|
安全 Java Android开发
构建高效Android应用:Kotlin与协程的完美融合
【2月更文挑战第15天】随着移动开发技术的不断进步,Android平台的开发者寻求更高效的编程解决方案以提升应用性能和用户体验。Kotlin作为官方推荐的开发语言,以其简洁性和功能安全性受到青睐。而协程,作为一种轻量级的线程管理机制,在异步编程和网络请求等方面展现出巨大潜力。本文将深入探讨Kotlin语言结合协程如何优化Android应用的性能,包括提高响应性、简化异步代码结构以及减少资源消耗等方面,旨在为开发者提供实战指南,帮助他们构建更加流畅和高效的Android应用。
|
7月前
|
安全 调度 数据库
Kotlin 学习笔记(五)—— 协程的基础知识,面试官的最爱了~(下)
Kotlin 学习笔记(五)—— 协程的基础知识,面试官的最爱了~(下)
43 0