IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android—Kotiln进阶教程(五) -> 正文阅读

[移动开发]Android—Kotiln进阶教程(五)

前言

在上一篇中对Kotlin协程里的调度器进行对应的讲解。在本篇中,将会对Kotlin协程对应上下文相关的知识点进行讲解。

1、上下文中的作业

协程的 Job 是上下文(CoroutineContext )的?部分,并且可以使? coroutineContext [Job] 表达式在上下?中检索它:

fun main() = runBlocking<Unit> {
    val job = launch {
        println("My job is ${coroutineContext[Job]}")
        //isActive
    }
    println(coroutineContext[Job]?.isActive)
    println(job.isActive)
}

CoroutineScope 中的 isActive 只是 coroutineContext[Job]?.isActive == true 的?种方便的快捷方式。

还记得之前的取消协程的判断不?就是通过判断上下文里面的isActive来检查取消的!

2、子协程

当?个协程被其它协程在 CoroutineScope 中启动的时候,它将通过CoroutineScope.coroutineContext 来承袭上下文,并且这个新协程的 Job 将会成为?协程作业的子作业(子协程)

来看看例子

// 启动?个协程来处理某种传?请求(request
fun main() = runBlocking<Unit> { //CoroutineScope

    val request = launch {
		// 孵化了两个?作业, 这个通过 GlobalScope 启动,这个不是子协程!
        GlobalScope.launch { //CoroutineScope
            log("job1: I run in GlobalScope and execute independently!")
            delay(2000) //这里挂起了2秒,再执行最后打印
            log("job1: I am not affected by cancellation of the request")
        }
		// 这个则承袭了?协程的上下? ,这个就是子协程!
        launch { //CoroutineScope
            delay(100)
            log("job2: I am a child of the request coroutine")
            delay(2000) //这里挂起了2秒,再执行最后打印
            log("job2: I will not execute this line if my parent request is cancelled")
        }
    }
 
    delay(500) //挂起500毫秒就取消
    request.cancel()
    delay(5000) //这里为了不让程序过早退出,所以等待5秒,
    log("main: Who has survived request cancellation?")
}

这里用上了上一篇的日志打印。

来看看运行效果

[DefaultDispatcher-worker-1] job1: I run in GlobalScope and execute independently!
[main] job2: I am a child of the request coroutine
[DefaultDispatcher-worker-1] job1: I am not affected by cancellation of the request
[main] main: Who has survived request cancellation?

通过这个运行效果我们可以看出:

  • 当?个父协程被取消的时候,所有它的子协程也会被递归的取消。
  • 当使用 GlobalScope 来启动?个协程时,则新协程的作业没有?作业,
    • 因此它与这个启动的作用域无关,且独立运作;
    • 所以说,当外部协程取消时,它并未受任何影响,直到运行完成。

3、父协程的职责

fun main() = runBlocking<Unit> {
    val request = launch {
        repeat(3){ i ->
            launch {
                delay((i + 1) * 200L)
                println("Coroutine $i is done")
            }
        }
        println("request: I'm done and I don't explicitly join my children that are still active")
    }
//    request.join()
    println("Now processing of the request is complete")
}

运行效果

Now processing of the request is complete
request: I'm done and I don't explicitly join my children that are still active
Coroutine 0 is done
Coroutine 1 is done
Coroutine 2 is done

从这个运行效果可以看出:

  • 当未使用job.join()时,父协程将会等待所有的子协程执行结束;
  • 当使用job.join()时,父协程将会等待所有子协程执行结束后,然后执行主协程的下一句(这个之前demo体验过,在这就不过多演示了,读者可以亲自尝试)

4、命名协程方便调试

这个很简单,直接上例子

fun main() = runBlocking<Unit> {
    log("Started main coroutine")

    val v1 = async(CoroutineName("v1coroutine")){
        delay(500L)
        log("Computing v1")
        252
    }

    val v2 = async(CoroutineName("v2coroutine")){
        delay(1000L)
        log("Computing v2")
        6
    }

    log("The answer for v1 / v2 = ${v1.await() / v2.await()}")
}

注意:这里使用了CoroutineName("v2coroutine") 将对应的协程命名为v2coroutine

来看看运行效果

[main] Started main coroutine
[main] Computing v1
[main] Computing v2
[main] The answer for v1 / v2 = 42

嗯?发现并没有 将对应协程的命名给打印出来!

如果读者也是这个结果,这时需要配置一下了。

在这里插入图片描述
如图所示

在这加上:-Dkotlinx.coroutines.debug=on

再次运行试试:

[main @coroutine#1] Started main coroutine
[main @v1coroutine#2] Computing v1
[main @v2coroutine#3] Computing v2
[main @coroutine#1] The answer for v1 / v2 = 42

4.1 组合上下文元素命名

fun main() = runBlocking<Unit> {
    launch(Dispatchers.Default + CoroutineName("test")) {
        println("I'm working in thread ${Thread.currentThread().name}")
    }
}

狠简单,在对应子协程里面加入了test命名。

看看运行效果

I'm working in thread DefaultDispatcher-worker-1 @test#2

结束语

好了,本篇到这里就结束了,同时对应的进阶教程也讲完了。以后将会以实战的方式来巩固Kotlin对应的知识点。从下一篇开始,将会继续回到对Gradle的讲解。

协程对应的所有代码:点我下载

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-11-22 12:27:21  更:2021-11-22 12:29:02 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 6:00:43-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码