金华建设学校继续教育网站济南开发网站
- 作者: 五速梦信息网
- 时间: 2026年03月21日 10:36
当前位置: 首页 > news >正文
金华建设学校继续教育网站,济南开发网站,设计官网公司,2021国内军事新闻大事件本系列文章 Android 上的协程#xff08;第一部分#xff09;#xff1a;了解背景 Android 上的协程#xff08;第二部分#xff09;#xff1a;入门 Android上的协程 (第三部分): 实际应用 Android 上的协程#xff08;第一部分#xff09;#xff1a;了解背景 这篇…本系列文章 Android 上的协程第一部分了解背景 Android 上的协程第二部分入门 Android上的协程 (第三部分): 实际应用 Android 上的协程第一部分了解背景 这篇文章重点介绍协程的工作原理以及它们解决的问题。 协程解决什么问题 Kotlin协程引入了一种新的并发方式可以在 Android 上使用它来简化异步代码。虽然协程在 1.3 中是 Kotlin 的新概念但协程的概念自编程语言诞生以来就一直存在。第一个探索使用协程的语言是1967 年的Simula。 在过去的几年中协程越来越受欢迎现在已包含在许多流行的编程语言中例如Javascript、C#、Python、Ruby和Go等等。Kotlin 协程基于已用于构建大型应用程序的既定概念。 在 Android 上协程可以很好地解决两个问题 长时间运行的任务是花费太长时间阻塞主线程的任务。 Main-safety允许您确保可以从主线程调用任何挂起函数。 让我们深入了解协程看看协程如何帮助我们以更简洁的方式构建代码 长时间运行的任务 获取网页或与 API 交互都涉及发出网络请求。类似地从数据库读取或从磁盘加载图像涉及读取文件。这些类型的事情就是我所说的长时间运行的任务——这些任务花费的时间太长以至于您的应用程序无法停止并等待它们 与网络请求相比现代手机执行代码的速度可能很难理解。在 Pixel 2 上单个 CPU 周期仅需不到 0.0000000004 秒这个数字很难用人类的术语来理解。但是如果您将网络请求视为一眨眼大约 400 毫秒0.4 秒就更容易理解 CPU 的运行速度。一眨眼的功夫或者一个有点慢的网络请求CPU 可以执行超过 10 亿个周期 在 Android 上每个应用程序都有一个主线程负责处理 UI如绘图视图和协调用户交互。如果此线程上发生过多工作应用程序似乎会挂起或变慢从而导致不良的用户体验。任何长时间运行的任务都应该在不阻塞主线程的情况下完成这样您的应用程序就不会显示所谓的“卡顿”如冻结的动画或者对触摸事件的响应缓慢。 为了在主线程之外执行网络请求一个常见的模式是回调。回调提供了一个库的句柄它可以用来在将来某个时间回调到您的代码中。使用回调的话获取developer.android.com上的数据可能是下面的样子 class ViewModel: ViewModel() {fun fetchDocs() {get(developer.android.com) { result -show(result)}} }即使get是从主线程调用它也会使用另一个线程来执行网络请求。然后一旦网络上的结果可用就会在主线程上调用回调。这是处理长时间运行任务的好方法像Retrofit这样的库可以帮助您在不阻塞主线程的情况下发出网络请求。 使用协同程序处理长时间运行的任务 协程是一种简化用于管理长时间运行任务如fetchDocs. 为了探索协程如何使长时间运行的任务的代码更简单让我们重写上面的回调示例以使用协程。 // Dispatchers.Main suspend fun fetchDocs() {// Dispatchers.Mainval result get(developer.android.com)// Dispatchers.Mainshow(result) } // look at this in the next section suspend fun get(url: String) withContext(Dispatchers.IO){/…/}这段代码不会阻塞主线程吗get它如何从没有返回结果等待网络请求并阻塞它事实证明协程为 Kotlin 提供了一种执行此代码且从不阻塞主线程的方法。 协程通过添加两个新操作建立在常规函数之上。除了invoke或 call和return之外协程还添加了suspend和resume。 suspend — 暂停当前协程的执行保存所有局部变量resume — 从暂停的地方继续暂停的协程 此功能由 Kotlin 通过函数上的 suspend 关键字添加。您只能从其他挂起函数调用挂起函数或者使用协程构建器如launch启动新协程。 Suspend 和 Resume 一起工作来代替回调。 在上面的示例中get将在启动网络请求之前暂停协程。该函数get仍将负责在主线程之外运行网络请求。然后当网络请求完成时它可以简单地恢复它挂起的协程而不是调用回调来通知主线程。 查看如何fetchDocs执行您可以了解suspend 的工作原理。每当协程挂起时都会复制并保存当前堆栈帧Kotlin 用来跟踪正在运行的函数及其变量的位置。当它恢复时堆栈帧从它保存的地方被复制回来并再次开始运行。在动画中间——当主线程上的所有协程都挂起时主线程可以自由地更新屏幕和处理用户事件。suspend 和 resume 一起替换回调。很简约 当主线程上的所有协程都挂起后主线程就可以自由地做其他工作了。 即使我们编写了看起来完全像阻塞网络请求的简单顺序代码协程也会按照我们的需要运行我们的代码并避免阻塞主线程 接下来让我们看看如何使用协程来实现主安全并探索调度程序。 协同程序的主要安全性 在 Kotlin 协程中编写良好的挂起函数始终可以安全地从主线程调用。不管他们做什么他们应该总是允许任何线程调用他们。 但是我们在 Android 应用程序中做的很多事情都太慢而无法在主线程上发生。网络请求、解析 JSON、从数据库读取或写入甚至只是遍历大型列表。其中任何一个都有可能运行缓慢到足以导致用户可见的“卡顿”并且应该在主线程之外运行。 使用suspend不会告诉 Kotlin 在后台线程上运行函数。值得清楚且经常说的是协程将在主线程上运行。事实上在启动协程以响应 UI 事件时使用Dispatchers.Main.immediate是一个非常好的主意——这样如果您最终没有执行需要 main-safety 的长时间运行的任务结果可以在下一帧中为用户提供。 协程会运行在主线程上挂起不代表后台。 Default要使一个对于主线程来说工作速度太慢的函数是主安全的您可以告诉 Kotlin 协程在 the或dispatcher上执行工作IO。在 Kotlin 中所有协程都必须在调度程序中运行——即使它们在主线程上运行也是如此。协程可以自行暂停而调度程序知道如何恢复它们。
为了指定协程应该在何处运行Kotlin 提供了三个可用于线程分派的分派器。
| Dispatchers.Main |
|---|
| Main thread on Android, interact |
| with the UI and perform light |
| work |
| - Calling suspend functions | | - Call UI functions |
| - Updating LiveData |
|---|
| Dispatchers.IO |
| Optimized for disk and network IO |
| off the main thread |
|---|
| - Database* |
| - Reading/writing files |
| - Networking** |
| Dispatchers.Default |
|---|
| Optimized for CPU intensive work |
| off the main thread |
| - Sorting a list | | - Parsing JSON | | - DiffUtils | ———————————–如果您使用挂起函数、RxJava或LiveData Room将自动提供主安全。 Retrofit和Volley等网络库管理它们自己的线程并且在与 Kotlin 协程一起使用时不需要在代码中显式维护主安全。 继续上面的示例让我们使用调度程序来定义函数get。get在您调用的主体内withContext(Dispatchers.IO) 创建一个将在IO调度程序上运行的块。您放入该块内的任何代码将始终在调度程序上执行IO。由于withContext它本身是一个挂起函数它将使用协程来提供主要安全性。 // Dispatchers.Main suspend fun fetchDocs() {// Dispatchers.Mainval result get(developer.android.com)// Dispatchers.Mainshow(result) } // Dispatchers.Main suspend fun get(url: String) // Dispatchers.MainwithContext(Dispatchers.IO) {// Dispatchers.IO/* perform blocking network IO here */}// Dispatchers.Main使用协程您可以使用细粒度控制进行线程分派。因为withContext允许您控制任何代码行在哪个线程上执行而无需引入回调来返回结果所以您可以将它应用于非常小的功能例如从数据库读取或执行网络请求。因此一个好的做法是withContext确保每个函数都可以安全地在任何Dispatcher包含上调用Main——这样调用者就不必考虑执行该函数需要什么线程。 在这个例子中fetchDocs在主线程上执行但可以安全地调用get它在后台执行网络请求。因为协程支持suspend和resume一旦块withContext完成主线程上的协程将恢复结果。 编写良好的挂起函数总是可以安全地从主线程或主线程调用。 使每个挂起函数都是主线程安全的是一个非常好的主意。如果它做任何涉及磁盘、网络的事情甚至只是使用过多的 CPU请使用withContext它来确保从主线程调用是安全的。这是 Retrofit 和 Room 等基于协程的库所遵循的模式。如果您在整个代码库中都遵循这种风格您的代码将会更加简单并且可以避免将线程问题与应用程序逻辑混在一起。如果始终遵循协程可以在主线程上自由启动并使用简单的代码发出网络或数据库请求同时保证用户不会看到“卡顿”。 withContext的表现 withContext与提供主要安全性的回调或 RxJava 一样快。在某些情况下甚至可以优化withContext调用使其超出回调所能达到的范围。如果一个函数将对数据库进行 10 次调用您可以告诉 Kotlin 在所有 10 次调用周围切换一次withContext。然后即使数据库 library 会对withContext重复调用它也会留在同一个调度程序上并遵循快速路径。此外对Dispatchers.Default和之间的切换Dispatchers.IO进行了优化以尽可能避免线程切换。 在这篇文章中我们探讨了协程最擅长解决的问题。协程是编程语言中一个非常古老的概念最近变得流行因为它们能够简化与网络交互的代码。 在 Android 上您可以使用它们来解决两个非常常见的问题 1.简化长时间运行任务的代码例如从网络、磁盘读取甚至解析大型 JSON 结果。 2.执行精确的 main-safety 以确保您不会意外阻塞主线程而不会使代码难以读写。
- 上一篇: 金华官方网站建设seo 网站分析
- 下一篇: 金华企业自助建站系统完全的图片宣传网站怎么做
相关文章
-
金华官方网站建设seo 网站分析
金华官方网站建设seo 网站分析
- 技术栈
- 2026年03月21日
-
金华公司建站模板做软装找图片的网站
金华公司建站模板做软装找图片的网站
- 技术栈
- 2026年03月21日
-
金华公司建站模板led网站制作
金华公司建站模板led网站制作
- 技术栈
- 2026年03月21日
-
金华企业自助建站系统完全的图片宣传网站怎么做
金华企业自助建站系统完全的图片宣传网站怎么做
- 技术栈
- 2026年03月21日
-
金华市建设技工学校教育培训网站wordpress可以做企业管理系统吗
金华市建设技工学校教育培训网站wordpress可以做企业管理系统吗
- 技术栈
- 2026年03月21日
-
金华市建设技工学校网站沈丘做网站yooker
金华市建设技工学校网站沈丘做网站yooker
- 技术栈
- 2026年03月21日
