协程的八种创建方式

在这里插入图片描述

协程简介

在深入了解创建方式之前,我们先简要回顾一下协程是什么。协程是轻量级的线程。它们在协作式多任务处理中运行,允许在不阻塞线程的情况下挂起和恢复。这使得协程非常适合进行异步编程和高性能的并发任务。🌐

Kotlin中创建协程的方式

Kotlin提供了多种方式来创建协程,每种方式都适用于不同的场景和需求。下面我们将一一探讨。

1. 使用launch函数

launch是最常用的创建协程的方法。它在CoroutineScope的上下文中启动一个新的协程。以下是使用launch函数的一个基本示例:

import kotlinx.coroutines.*

fun main() {
 val scope = CoroutineScope(Dispatchers.Default)
 scope.launch {
     println("This is run in a coroutine")
 }
}

在上面的示例中,launch函数创建了一个协程,该协程在Dispatchers.Default调度器上执行,通常用于CPU密集型任务。👨‍💻

2. 使用asyncawait

async函数与launch类似,但它返回一个Deferred对象,该对象是一个轻量级的非阻塞future,表示一个可能尚未完成的异步计算。async常用于需要并发计算结果的场景。一旦协程完成,可以使用await方法获取结果。这是一个示例:

import kotlinx.coroutines.*

fun main() {
 val scope = CoroutineScope(Dispatchers.Default)
 val deferredResult = scope.async {
     delay(1000L) // 模拟异步任务
     return@async "Result from coroutine"
 }
 runBlocking {
     println("Waiting for result...")
     val result = deferredResult.await()
     println("Received result: $result")
 }
}

上面的代码展示了如何使用async启动一个协程,并在其完成时使用await获取结果。📦

3. 使用runBlocking

runBlocking是一个特殊的协程构建器,它会阻塞当前线程来等待协程完成。这通常不推荐在生产代码中使用,但它对于测试和一次性的任务非常有用,尤其是在需要从协程中直接返回结果时。下面是一个使用runBlocking的示例:

import kotlinx.coroutines.*

fun main() {
 println("Before runBlocking")
 runBlocking {
     delay(1000L) // 模拟耗时任务
     println("Inside runBlocking")
 }
 println("After runBlocking")
}

上面的示例展示了runBlocking如何在协程内部执行任务,同时阻塞主线程直到协程执行完毕。🚦

4. 使用coroutineScope

coroutineScope是另一个协程构建器,它创建一个新的协程作用域,并且只有当所有在这个作用域内启动的协程都完成时,才会继续向下执行。这对于在并发程序中进行结构化并发非常有用。示例如下:

import kotlinx.coroutines.*

suspend fun performTask() {
 coroutineScope { // 创建一个协程作用域
     launch {
         delay(1000L)
         println("Task 1 completed")
     }
     launch {
         delay(1000L)
         println("Task 2 completed")
     }
     println("coroutineScope will wait for all children to complete")
 }
 println("All children are complete")
}

fun main() {
 runBlocking {
     performTask()
 }
}

在上述代码中,performTask函数中的coroutineScope确保所有启动的协程(两个launch)都执行完成后,才会打印最后的消息。🔗

5. 使用supervisorScope

supervisorScopecoroutineScope相似,但它有一个关键的区别:在supervisorScope中,一个子协程的失败不会导致其他子协程的取消。这非常适合那些子任务可能相互独立且一个任务的失败不应该影响其他任务的场景。示例如下:

import kotlinx.coroutines.*

suspend fun performSupervisedTask() {
 supervisorScope {
     val childOne = launch {
         println("Child one is running")
         throw Exception("Child one failure")
     }
     val childTwo = launch {
         delay(1000L)
         println("Child two is running")
     }
     try {
         childOne.join()
         childTwo.join()
     } catch (e: Exception) {
         println("Caught an exception from child one: ${e.message}")
     }
 }
}

fun main() {
 runBlocking {
     performSupervisedTask()
 }
}

在这个示例中,尽管childOne抛出了一个异常,但childTwo仍然能够继续执行。这是supervisorScope的主要优势。🛡️

6. 使用lifecycleScope

在Android开发中,lifecycleScope是专门为处理与生命周期绑定的协程而设计的。这个作用域自动与Activity或Fragment的生命周期绑定,确保协程在Lifecycle所有者(如Activity或Fragment)销毁时自动取消。这种方式非常适合用于UI相关的任务,如网络请求或数据库操作。以下是一个例子:

import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.*

fun MainActivity.someFunction() {
 lifecycleScope.launch {
     delay(1000L) // 模拟耗时操作
     updateUI() // 更新UI
 }
}

fun updateUI() {
 // 更新UI的代码
}

在这个示例中,协程在MainActivitylifecycleScope中启动,确保如果MainActivity被销毁,协程也会相应地被取消。🏠

7. 使用viewModelScope

viewModelScope是绑定到Android的ViewModel的生命周期的。这个作用域确保协程只在ViewModel存活期间活动,并在ViewModel清除时自动取消所有协程。这对于处理需要在用户界面与后端之间进行长时间运行操作的应用程序非常有用。示例如下:

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.*

class MyViewModel : ViewModel() {
 fun performNetworkOperation() {
     viewModelScope.launch {
         val data = networkCall() // 网络请求
         processData(data) // 处理数据
     }
 }

 suspend fun networkCall(): String {
     delay(1000L) // 模拟网络延迟
     return "Network data"
 }

 fun processData(data: String) {
     // 处理接收到的数据
 }
}

在这个示例中,MyViewModel中的协程是在viewModelScope内部启动的,这意味着只要ViewModel未被清除,协程就可以安全地执行。🔍

8. 使用GlobalScope

GlobalScope是一个全局协程作用域,它的生命周期只受整个应用程序的生命周期限制。使用GlobalScope启动的协程在应用程序的任何部分都可以运行,且只会在应用程序完全停止时才会被取消。尽管它在某些情况下看起来很方便,但通常不推荐使用GlobalScope,因为它可能会导致内存泄漏和其他生命周期问题。示例代码如下:

import kotlinx.coroutines.*

fun performGlobalOperation() {
 GlobalScope.launch {
     delay(5000L) // 模拟长时间运行的任务
     println("Global scope operation")
 }
}

在这个示例中,即使用户离开了启动这个协程的界面,协程仍将继续执行,直到任务完成。🌍

  • 20
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jiet_h

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值