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 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Kotlin-协程Coroutines-基本了解 -> 正文阅读

[移动开发]Kotlin-协程Coroutines-基本了解

Kotlin中的异步编程:https://kotlinlang.org/docs/async-programming.html#threading

一些处理异步的方案:

  • Threading
  • Callbacks
  • Futures, promises, and others
  • Reactive Extensions
  • Coroutines

协程Coroutines

kotlinx.coroutines 协程库,包含很多丰富的api

使用协程api需要添加依赖,java用java依赖,android用android依赖

dependencies {
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0")
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.0")
}

协程是一个可暂停运行的实例,它需要在block代码块中来运行。协程并不绑定到任何特定的线程。
协程可以在一个线程中暂停,在另一个线程中唤醒。
协程可以被认为是轻量级线程,但有很多重要的区别

Your first coroutine

runBlocking launch 都是协程库里的函数

fun main() {

    runBlocking {
         launch {
            delay(1000)
            println("world")
        }
        launch {
            delay(500)
            println("world2222")
        }
        println("hello")
        delay(3000)
    }
    // 先执行上面的协程代码阻塞并执行完毕,最后执行下面这一行
 	println("over")
}

先输出hello,0.5秒后输出world2222,1秒后输出world,最后输出over

launch{} 是一个协程构建者,它启动一个协程block代码块,该block独立运行。

delay() 是一个特殊的暂停or悬挂函数

runBlocking{} 也是一个协程构建者,它运行一个协程并中断阻塞当前线程,直到协程block中的代码运行完。
设计目的就是为了让普通代码具有暂停or悬挂or阻塞功能,可以放到主函数或者测试中使用。真实代码很少使用

Structured concurrency 结构化并发概念:阐述了协程的生命周期及运行范围。
协程的启动及运行只能在特定的协程范围CoroutineScope内。 协程范围外的代码必须要等协程内部block代码运行外才能运行。println(“over”)必须要等待runBlocking{}执行完,才能运行。

Extract function refactoring
可以将协程block中的代码,抽取成一个方法,用suspend修饰符

fun main() = runBlocking { // this: CoroutineScope
    launch { doWorld() }
    println("Hello")
}

// this is your first suspending function
suspend fun doWorld() {
    delay(1000L)
    println("World!")
}

Scope builder coroutineScope{}函数

协程代码块可以通过不同的构建器生成,也可以通过coroutineScope{}来生成。通过 coroutineScope{}来生成的协程,必须要等其及子项的block代码块运行完,才能结束

runBlocking和coroutineScope的构建者可能看起来很相似,
主要区别在于:
runBlocking{}阻塞当前线程,其他资源不能被使用。
coroutineScope{}暂停当前线程,释放底层线程供其他使用,所以其是一个suspend暂停函数

可以在任何suspend暂停函数中使用coroutineScope{}

fun main() = runBlocking {
    doWorld("World!", 2000)
    println("over")

}

suspend fun doWorld(str: String, delayTime: Long) = coroutineScope {
    launch {
        delay(delayTime)
        println(str)
    }
    println("hello")
}

coroutineScope{}可以在suspend暂停函数中执行并发操作
比如开启多个launch{} ,多个协程运行完,coroutineScope{}才结束

suspend fun doWorld() = coroutineScope { // this: CoroutineScope
    launch {
        delay(2000L)
        println("World 2")
    }
    launch {
        delay(1000L)
        println("World 1")
    }
    println("Hello")
}

An explicit job: Job类
launch {} 函数的返回值是Job对象
job.join() 暂停协程,等待job及其子协程完成

public fun CoroutineScope.launch(
    context: CoroutineContext = EmptyCoroutineContext,
    start: CoroutineStart = CoroutineStart.DEFAULT,
    block: suspend CoroutineScope.() -> Unit
): Job{}
val job = launch { // launch a new coroutine and keep a reference to its Job
        delay(1000L)
        println("World!")
    }
    println("Hello")
    job.join() // wait until child coroutine completes
    println("Done")

Job类的方法:
在这里插入图片描述

Coroutines ARE light-weight 协程轻便,占用资源少

试试下面的代码

fun main() = runBlocking {
    repeat(100_000) { // launch a lot of coroutines
        launch {
            delay(5000L)
            print(".")
        }
    }
}

改用原始方式:
去掉runBlocking{} ,launch{}替换为Thread,delay()改为Thread.sleep, 然后再次运行试试

Thread(){
   Thread.sleep(5000)
    print(".")
}.start()

协程的取消

job.cancel() job.join()要配合使用
或者用job.cancelAndJoin()

判断协程状态用属性 isActive 当前协程还在处理中,没有完成也没有被取消

val job = launch {
    repeat(1000) { i ->
        println("job: I'm sleeping $i ...")
        delay(500L)
    }
}
delay(1300L) // delay a bit
println("main: I'm tired of waiting!")
job.cancel() // cancels the job
job.join() // waits for job's completion 

// cancel() join()要配合使用

println("main: Now I can quit.")

不可取消的协程
用withContext(NonCancellable) {}

val job = launch {
    try {
        repeat(1000) { i ->
            println("job: I'm sleeping $i ...")
            delay(500L)
        }
    } finally {
        withContext(NonCancellable) {
            println("job: I'm running finally")
            delay(1000L)
            println("job: And I've just delayed for 1 sec because I'm non-cancellable")
        }
    }
}
delay(1300L) // delay a bit
println("main: I'm tired of waiting!")
job.cancelAndJoin() // cancels the job and waits for its completion
println("main: Now I can quit.")

协程的超时
用withTimeout(){}函数,超时会报异常
withTimeoutOrNull(){}函数,超时返回null

withTimeout(1300L) {
    repeat(1000) { i ->
        println("I'm sleeping $i ...")
        delay(500L)
    }
}
  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-03-04 15:44:08  更:2022-03-04 15:46:16 
 
开发: 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 17:23:14-

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