<>如何使用 Kotlin 协程执行顺序后台任务
Kotlin 协程,谁不知道协程!因此,在这篇文章中,我们会讲到其中一个重要的部分,就是制作顺序后台任务。
大家好,我是 Abanoub,在这篇文章中,我将向您展示如何使用async和await以及使用withContext
的另一种方法使用协程来执行顺序后台任务。
顺序意味着如果你有3个任务,第一个任务将运行,第二个任务将在第一个任务完成后执行,第三个任务将在第二个任务完成后执行,依此类推。
1. 添加协程依赖
您需要将 kotlin 协程依赖项添加到您的build.gradle应用程序模块:
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4'
然后同步你的项目,让我们开始吧。
2. 创建一个CoroutineScope 实例。
这将定义协程将在其中运行的上下文。
val myScope = CoroutineScope(Dispatchers.IO)
3.创建一些后台任务作为挂起函数
suspend fun doTask1() { repeat(5) { i -> Log.d("CoroutinesTasks", "doTask1: $i"
) } } suspend fun doTask2() { repeat(5) { i -> Log.d("CoroutinesTasks",
"doTask2:$i") } } suspend fun doTask3() { repeat(5) { i -> Log.d(
"CoroutinesTasks", "doTask3: $i") } }
现在我们已经创建了三个挂起函数,每个函数将打印一条日志 5 次,这是对后台任务的简单模拟,例如使用 Room 或 Retrofit 制作任务。
4. 使用异步和等待
要按顺序运行这些任务,您可以使用async和await函数。async 创建一个新的 Coroutine 并返回一个Deferred对象,而await等待
Coroutine 的结果并返回它的值。
val myScope = CoroutineScope(Dispatchers.IO) myScope.launch { Log.d(
"CoroutinesTasks", "onCreate: Started") val result1 = async { doTask1() }.await(
) val result2 = async { doTask2() }.await() val result3 = async { doTask3() }.
await() Log.d("CoroutinesTasks", "onCreate: Ended") }
在此示例中,我们使用async按顺序运行每个任务,并使用await等待其结果。这确保了每个任务都按照我们想要的顺序执行,而不会阻塞主线程。
现在,如果你运行这个应用程序,你会看到这样的结果:
* 开始执行第一个任务,直到第一个任务完成后才执行第二个任务。
* 第一个任务完成,其结果存储在 result1 变量中。
* 开始执行第二个任务,直到第二个任务完成后才开始执行第三个任务。
* 第二个任务完成,它的结果存储在 result2 变量中。
* 开始执行第三个任务,直到第三个任务完成后才开始执行它之后的任何事情。
* 第三个任务完成,结果保存在result3变量中。 D onCreate: Started D doTask1: 0 D doTask1: 1 D
doTask1:2 D doTask1: 3 D doTask1: 4 D doTask2: 0 D doTask2: 1 D doTask2: 2 D
doTask2:3 D doTask2: 4 D doTask3: 0 D doTask3: 1 D doTask3: 2 D doTask3: 3 D
doTask3:4 D onCreate: Ended
那么,什么是result1、result2、result3呢?
这些是结果,假设你在第一个任务中从 api 中获得了一个数据列表,那么 result1 将是这个列表,但是 suspend
函数返回类型应该是你想要作为结果获取它的数据,并且在第二个任务中,你会将这个列表保存到数据库中,然后你将它正常传递给第二个任务,我们将在一个例子中解释这一点。
5. 使用withContext()
您也可以使用withContext函数获得相同的结果。
val myScope = CoroutineScope(Dispatchers.IO) myScope.launch { Log.d(
"CoroutinesTasks", "onCreate: Started") val result1 = withContext(Dispatchers.IO
) { doTask1() } val result2 = withContext(Dispatchers.IO) { doTask2() } val
result3= withContext(Dispatchers.IO) { doTask3() } Log.d("CoroutinesTasks",
"onCreate: Ended") }
例子:
将顺序后台任务定义为单独的挂起函数。例如,如果你想执行一个网络请求,然后是数据库访问,你可以定义两个单独的挂起函数:
suspend fun fetchPosts(): List<Post> { // Perform network request return myApi.
getPosts() } suspend fun savePosts(posts: List<Post>) { // Save data to database
myDao.savePosts(posts) }
在 withContext 块中一个接一个地调用顺序后台任务。这将确保每个任务按顺序运行并且不会阻塞 UI 线程。例如:
myScope.launch { val posts = withContext(Dispatchers.IO) { fetchPosts() }
withContext(Dispatchers.IO) { savePosts(posts) } }
本例首先调用fetchPosts进行网络请求,结果保存到posts变量中。然后,使用posts变量作为输入调用savePosts
以将帖子保存到数据库中。这两个任务在同一个协程范围内顺序运行。