kotlin协程runBlocking和coroutineScope(三)

一、前言

虽然之前已经讲了两篇协程,不过本篇还是协程基础。本篇主要是从kotlin官网上了解的关于协程的相关内容

二、相关依赖

如果只是使用协程的话,可以使用下面的依赖。下面的库并不依赖于Android环境:

dependencies {
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.1'
 // implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-//android:1.5.1' android上则需要改为这个依赖项
}

buildscript {
    ext.kotlin_version = '1.5.20'
}
repository {
    mavenCentral()
}

三、runBlocking和coroutineScope

有时候我们会看到这两个函数,根据官方介绍,runBlocking会阻塞当前线程等待,coroutineScope会挂起释放底层线程用作他用。用以下来解释他们的区别

首先看runBlocking

class ExampleUnitTest {
    @Test
    fun addition_isCorrect() {
//        assertEquals(4, 2 + 2)
      		testCoroutines()
    }

    private fun testCoroutines(){
        println("000000")
           runBlocking {
               delay(1000)
               println("11runBlocking")
           }
        println("22222")
    }

}

运行后可以看到以下结果

000000
11runBlocking
22222

Process finished with exit code 0

我们再看coroutineScope

class ExampleUnitTest {
    @Test
    fun addition_isCorrect() {
//        assertEquals(4, 2 + 2)
        GlobalScope.launch {
            testCoroutines()
        }
    }

    private suspend fun testCoroutines(){
        println("000000")
        coroutineScope {
            delay(1000)
            println("11runBlocking")
        }
        println("22222")
    }

}

首先可以发现testCoroutines()中多了一个suspend的挂起修饰符。其次需要用GlobalScope.launch {}包括该函数。说明runBlocking自己就有作用域,而coroutineScope没有,而且这是一个挂起函数,需要被其它挂起函数或者协程启动。然后我们看运行结果

Process finished with exit code 0

会发现什么都没有(因为程序执行完了,所以里面东西没有打印就不打印了),这时候我们明白了,为什么runBlocking是阻塞线程,而coroutineScope是挂起函数,没有阻塞线程。

四、为什么runBlocking可以直接启动协程

launchasync、 或runBlocking用于启动新的协程时,它们会自动创建相应的作用域。所有这些函数都以一个带有接收器的 lambda 作为参数,隐式接收器类型是CoroutineScope

launch{ /* this: CoroutineScope */
}

新的协程只能在一个范围内启动。 launch并且async被声明为对 的扩展CoroutineScope,因此当我们调用它们时必须始终传递隐式或显式接收器。由启动的协程runBlocking是唯一的例外:runBlocking被定义为顶级函数。但是因为它阻塞了当前线程,所以它主要用于main函数和测试中作为桥接函数。

五、launch、async

启动协程有两个方式,通过launch或者async。

  • launch 可启动新协程而不将结果返回给调用方。任何被视为“一劳永逸”的工作都可以使用 launch 来启动。
  • async会启动一个新的协程,并允许您使用一个名为 await 的挂起函数返回结果。

通常,您应使用 launch 从常规函数启动新协程,因为常规函数无法调用 await。只有在另一个协程内时,或在挂起函数内且正在执行并行分解时,才使用 async

警告launchasync 处理异常的方式不同。由于 async 希望在某一时刻对 await 进行最终调用,因此它持有异常并将其作为 await 调用的一部分重新抛出。这意味着,如果您使用 async 从常规函数启动新协程,则能以静默方式丢弃异常。这些丢弃的异常不会出现在崩溃指标中,也不会在 logcat 中注明。如需了解详情,请参阅协程中的取消和异常

如下方式才是对协程的启动

private  fun testCoroutines(){
    println("000000")
    runBlocking {
        launch {
            delay(1000)
            println("11runBlocking---launch")
        }
        async {
            delay(1000)
            println("11runBlocking---async")
        }
        println("11runBlocking---end")
    }
    println("22222")
}

三、参考链接

  1. kotlin相关依赖:

    https://github.com/Kotlin/kotlinx.coroutines/blob/master/README.md#using-in-your-projects

  2. Kotlin的协程基础

    https://play.kotlinlang.org/hands-on/Introduction%20to%20Coroutines%20and%20Channels/04_Suspend

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Kotlin 中,可以使用协程来实现异步操作。如果需要在协程执行完后再执行下一句,可以使用 `runBlocking` 函数或者 `CoroutineScope.launch` 函数的 `join` 方法。 `runBlocking` 函数会阻塞当前线程,直到内部的协程执行完毕。因此,可以将需要等待协程执行完毕后再执行的代码放在 `runBlocking` 函数的后面。 举个例子,假设我们有一个协程函数 `fetchData`,它会异步地从网络中获取数据: ```kotlin suspend fun fetchData(): String { delay(3000) return "Data from network" } ``` 如果我们想要在协程执行完后输出数据,可以这样写: ```kotlin fun main() = runBlocking<Unit> { val data = fetchData() println(data) } ``` 在这个例子中,我们使用 `runBlocking` 函数来阻塞主线程,并在内部启动协程来执行 `fetchData` 函数。当协程执行完毕后,`runBlocking` 函数会返回,我们就可以在后面的代码中使用协程返回的数据了。 另外,如果我们使用 `CoroutineScope.launch` 函数来启动协程,可以在协程对象上调用 `join` 方法来等待协程执行完毕。例如: ```kotlin fun main() = runBlocking<Unit> { val job = launch { val data = fetchData() println(data) } job.join() println("Coroutine finished") } ``` 在这个例子中,我们使用 `launch` 函数来启动协程,并将返回的 `Job` 对象保存下来。然后,在协程执行完毕后,我们调用 `join` 方法来等待协程执行完毕。最后,我们可以在后面的代码中执行其他操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值