Kotlin之协程(第七趴)--在高阶函数中使用协程&;and;将协程与工作经理结合使用
作者:访客发布时间:2023-12-13分类:程序开发学习浏览:112
1个、在高阶函数中使用协程
您将重构MainViewModel
中的refreshTitle
、以使用常规的数据加载函数.
refreshTitle
的当前实现运行正常,但我们可以创建一个始终显示旋转图标的常规数据加载协程.对于加载数据以影响多个事件且希望确保加载旋转图标始终显示的代码库,这可能非常有用.
查看当前实现,可以发现,除reppository.refreshTitle()
之外的每行代码都是显示旋转图标和错误的样板代码.
// MainViewModel.kt
fun refreshTitle() {
viewModelScope.launch {
try {
_spinner.value = true
// this is the only part that changes between sources
repository.refreshTitle()
} catchh (error: TitleRefreshError) {
_snackBar.value = error.message
} finally {
_spinner.value = false
}
}
}
重要提示:虽然我们在此代码中仅适用viewModelScope,但通常可以在任何意义的位置添加作用于。如果不再需要它,记得将其取消。
例如,您可以在RecyclerView Adapter中声明一个作用域,以执行DiffUtil操作。
1.1、在高阶函数中使用协程
将以下代码添加到MainViewModel.kt中MainViewModel.kt
private fun launchDataLoad(block: suspend () -> Unit): Job {
return viewModelScope.launch {
try {
_spinner.value = true
block()
} catch (error: TitleRefreshError) {
_snackBar.value = error.message
} finally {
_spinner.value = false
}
}
}
现在重构refreshTitle()
以使用此高阶函数.MainViewModel.kt
fun refreshTitle() {
launchDataLoad {
repository.refreshTitle()
}
}
通过抽象化用于显示加载旋转图标和显示错误的逻辑,我们简化了加载数据所需的实际代码.显示旋转图标或显示错误是易于泛化到任何数据加载的内容,而实际数据源和目标则需要每次都指定.
为了构建此抽象,launchDataLoad
接受一个属于挂起Lambda的参数block
那就是。挂起Lambda可让您调用挂起函数.Kotlin就是通过这种方式实现我们在此代码中使用的launch
和runBlocking
协程构建器.
// suspend lambda
block: suspend () -> Unit
要创建挂起Lambda,应从suspend
关键字着手.函数的箭头和返回值类型Unit
用于完成声明.
您通常不必声明自己的挂起Lambda,但它们可能有助于创建这类封装重复逻辑的抽象!
2个、将协程与工作经理结合使用
本部分,您将学习如何从工作经理使用基于协程的代码。
2.1、什么是工作管理器
安卓有多个选项用于处理可延迟的后台工作。本练习介绍如何将WorkManager
与协程集成.工作经理是一个兼容、灵活且简单的库,用于处理可延迟的后台工作。工作经理是安卓中这些用例的推荐解决方案。
工作经理属于安卓Jetpack的一部分,是一种架构组件,用于处理既需要机会性执行,又需要有保证的执行的后台工作。机会性执行意味着工作经理会尽快执行您的后台工作。有保证的执行意味着工作经理会负责通过逻辑保障在各种情况下启动您的工作,即使用户离开您的应用也无妨。
因此,工作经理适合最终必须完成的任务。
以下是一些适合使用工作经理的任务的典型示例:
- 上传日志
- 对图片应用滤镜并保存图片
- 定期将本地数据与网络同步
2.2、将协程与工作经理一起使用
工作经理为不同用例提供其基本ListenableWorker
类的不同实现.
最简单的Worker类可让我们通过工作经理执行一些同步操作。不过,根据目前为止我们将代码库转换为使用协程和挂起函数的经验,我们发现使用工作管理器的最好方法是通过CoroutineWorker
类,此类支持将doWork()
函数定义为挂起函数.
首先,请打开refreshMainDataWork
那就是。它已扩展了CoroutineWorker
,您需要实现doWork
那就是。
在suspend doWork
函数中,从代码库中调用refreshTitle()
并返回响应的结果.
完成TODO后,代码将如下所示.
override suspend fun doWork(): Result {
val database = getDatabase(applicationContext)
val repository = TitleRepository(network, database.titleDao)
return try {
repository.refreshTitle()
Result.success()
} catch (error: TitleRefreshError) {
Result.failure()
}
}
请注意,CoroutineWorker.doWork()
是一个挂起函数.与更简单的Worker
类不同,此代码不会在您的工作管理器配置所指定的执行器上运行,而是使用coroutineContext
成员的调度程序(默认为Dispatchers.Default
)
2.3、测试我们的协作员
工作经理提供了几种不同的Worker
类测试方法.
工作管理器v2.1引入了一组新的API来支持更简单的ListenableWorker
类测试方法,并最终推出了CoroutineWorker。我们将在代码中使用一个名为TestListenableWorkerBuilder
的新接口。
为了添加我们的新测试,更新androidTest
文件夹下的RefreshMainWorkTest
文件.
此文件的内容为:
package com.example.android.kotlincoroutines.main
import android.content.Context
import androidx.test.core.app.ApplicationProvider
import androidx.work.ListenableWorker.Result
import android.content.Context
import androidx.test.core.app.ApplicationProvider
import androidx.work.ListenableWorker.Result
import androidx.work.testing.TestLiestenableWorkerBuilder
import com.example.android.kotlincoroutines.fakes.MainNetworkFake
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Junit4
@RunWith(JUnit4::class)
class RefreshMainDataWorkTest {
@Test
fun testRefreshMainDataWork() {
val fakeNetwork = MainNetworkFake("OK")
val context = ApplicationProvider.getApplicationContext<Context>()
val worker = TestListenableWorkerBuilder<RefreshMainDataWork>(context)
.setWorkerFactory(RefreshMainDataWork.Factory(fakeNetwork))
.build()
// Start the work synchronously
val result = worker.startWork().get()
assertThat(result).isEqualTo(Result.success)
}
}
在执行测试之前,我们会先告知WorkManager
关于工厂的信息,以便我们注入虚构网络.
测试本身会使用TestListenableWorkerBuilder
创建我们的工作器,然后我们可以运行该工作器来调用startWork()
方法.
WorkManager只是用来说明如何使用协程简化接口设计的一个示例。
- 程序开发学习排行
-
- 1鸿蒙HarmonyOS:Web组件网页白屏检测
- 2HTTPS协议是安全传输,为啥还要再加密?
- 3HarmonyOS鸿蒙应用开发——数据持久化Preferences
- 4记解决MaterialButton背景颜色与设置值不同
- 5鸿蒙HarmonyOS实战-ArkUI组件(RelativeContainer)
- 6鸿蒙HarmonyOS实战-ArkUI组件(Stack)
- 7[Android][NDK][Cmake]一文搞懂Android项目中的Cmake
- 8Android广播如何解决Sending non-protected broadcast问题
- 9鸿蒙HarmonyOS实战-ArkUI组件(mediaquery)
- 最近发表
-
- WooCommerce最好的WordPress常用插件下载博客插件模块的相关产品
- 羊驼机器人最好的WordPress常用插件下载博客插件模块
- IP信息记录器最好的WordPress常用插件下载博客插件模块
- Linkly for WooCommerce最好的WordPress常用插件下载博客插件模块
- 元素聚合器Forms最好的WordPress常用插件下载博客插件模块
- Promaker Chat 最好的WordPress通用插件下载 博客插件模块
- 自动更新发布日期最好的WordPress常用插件下载博客插件模块
- WordPress官方最好的获取回复WordPress常用插件下载博客插件模块
- Img to rss最好的wordpress常用插件下载博客插件模块
- WPMozo为Elementor最好的WordPress常用插件下载博客插件模块添加精简版