Kotlin 单元测试

runBlocking { …… } 作为用来启动顶层主协程的适配器。 指定了其返回类型 Unit, Kotlin 中 main 函数必须返回 Unit 类型。

import kotlinx.coroutines.runBlocking
import org.junit.Test

class MyTest {

    @Test
    fun  test() = runBlocking<Unit> {
        // 这里我们可以使用任何喜欢的断言风格来使用挂起函数
        print("=====>test")
    }
}

等待一个线程执行

显式(以非阻塞方式)等待所启动的后台 Job 执行结束

import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking

/**
 * 以非阻塞方式)等待所启动的后台 Job 执行结束
 * 说明:主协程与后台作业的持续时间没有任何关系
 */
suspend fun main() {

    val job = GlobalScope.launch {//后台启动一个新的协程并启动
        delay(1000)
        println("========>Hello,coroutines")
    }
    println("Hello")// 主线程中的代码会立即执行

    job.join() // 等待直到子协程执行结束 需要在方法里面加关键字suspend

}

协程结构化

使用 runBlocking 协程构建器将 main 函数转换为协程。 包括 runBlocking 在内的每个协程构建器都将 CoroutineScope 的实例添加到其代码块所在的作用域中。 在这个作用域中启动协程而无需显式 join 之,因为外部协程( runBlocking)直到在其作用域中启动的所有协程都执行完毕后才会结束

import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking

/**
 * 使用结构化并发-->可以在执行操作所在的指定作用域内启动协程,
 * 而不是像通常使用线程(线程总是全局的)在 GlobalScope 中启动。
 */
 fun main()  = runBlocking{

    launch {
        // 在 runBlocking 作用域中启动一个新协程
        delay(1000L)
        println("World!")
    }

    println("Hello,")

}

作用域构建器

可以使用 coroutineScope 构建器声明自己的作用域。创建一个协程作用域并且在所有已启动子协程执行完毕之前不会结束。

import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking

/**
 * runBlocking 与 coroutineScope
 * 共同点:都会等待其协程体以及所有子协程结束。
 * 主要区别:
 * 1、runBlocking 方法会阻塞当前线程来等待, 而 coroutineScope 只是挂起,会释放底层线程用于其他用途。
 * 2、runBlocking 是常规函数,而 coroutineScope 是挂起函数。
 */
 fun main()  = runBlocking{

    launch {
        // 在 runBlocking 作用域中启动一个新协程
        delay(1000L)
        println("Hello,runBlocking!")
    }

    //coroutineScope 构建器声明作用域。
    // 创建一个协程作用域并且在所有已启动子协程执行完毕之前不会结束。
    coroutineScope { // 创建一个协程作用域
        launch {
            delay(500L)
            println("Task from nested coroutineScope")
        }
    }

    println("Hello,")

//    output:
//    Task from nested coroutineScope
//            Hello,
//    Hello,runBlocking!

}

协程提取函数重构

将 launch { …… } 内部的代码块提取到独立的函数中。执行“提取函数”重构时,会得到一个带有 suspend 修饰符的新函数。 这是一个挂起函数。在协程内部可以像普通函数一样使用挂起函数
特性:同样可以使用其他挂起函数(delay)来挂起协程的执行。

import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking

/**
 * 将 launch { …… } 内部的代码块提取到独立的函数中
 * 需要使用关键字suspend来修饰此独立函数
 * 在协程内部可以像普通函数一样使用挂起函数
 * 同样可以使用其他挂起函数(如: delay)来挂起协程的执行
 */
 fun main()  = runBlocking{

    launch {
        // 在 runBlocking 作用域中启动一个新协程
        doWorld()
    }

    println("next")

//    output
//    next
//    World!


}

/**
 * 拓展:怎么提取出的函数包含一个在当前作用域中调用的协程构建器?
 *  1、加上suspend关键字
 *  2、使用CoroutineScope(coroutineContext),这种方法结构上不安全,
 *  因控制该方法执行的作用域。只有私有 API 才能使用CoroutineScope(coroutineContext)。
 */
suspend fun doWorld() {
    delay(1000L)
    println("World!")
}

协程轻量性使用

import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking

/**
 *
 *  协程是轻量级线程
 */
suspend fun main() = runBlocking{

    //启动了 10 万个协程,并且在 5 秒钟后,每个协程都输出一个点

    repeat(100_000) { // 启动大量的协程
        launch {
            delay(5000L)
            print(".\t")
        }
    }

}

全局守护协程

import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

/**
 * 全局守护线程 限时结束
 *  GlobalScope 中启动了一个长期运行的协程
 */
suspend fun main() {

    GlobalScope.launch {
        repeat(1000) { i ->
            println("i == $i")
            delay(500)
        }
    }

    delay(100000)

}
Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐