国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Kotlin 協(xié)程基礎(chǔ)使用學(xué)習(xí)

這篇具有很好參考價(jià)值的文章主要介紹了Kotlin 協(xié)程基礎(chǔ)使用學(xué)習(xí)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

原文: Kotlin 協(xié)程基礎(chǔ)使用學(xué)習(xí)-Stars-One的雜貨小窩

本篇閱讀可能需要以下知識(shí),否則可能閱讀會(huì)有些困難

  • 客戶端開發(fā)基礎(chǔ)(Android開發(fā)或JavaFx開發(fā))
  • Java多線程基礎(chǔ)
  • kotlin基礎(chǔ)

本文盡量以使用為主,以代碼為輔講解,不提及過深協(xié)程底層代碼邏輯,僅做一個(gè)基礎(chǔ)入門來快速上手學(xué)習(xí)(斷斷續(xù)續(xù)寫了好幾個(gè)周,若是有錯(cuò)誤之處也請(qǐng)?jiān)谠u(píng)論區(qū)提出 ??)

協(xié)程優(yōu)點(diǎn)

首先,先說下為什么使用協(xié)程吧

協(xié)程得和線程進(jìn)行比較

  • 可在單個(gè)線程運(yùn)行多個(gè)協(xié)程,其支持掛起,不會(huì)使運(yùn)行協(xié)程的線程阻塞。
  • 協(xié)程可以取消
  • 協(xié)程可以讓異步代碼同步化,其本質(zhì)是輕量級(jí)線程,進(jìn)而可以降低異步程序的設(shè)計(jì)復(fù)雜度。

對(duì)于客戶端的網(wǎng)絡(luò)請(qǐng)求數(shù)據(jù),以往寫法都是在回調(diào)操作里進(jìn)行更新UI操作,一旦業(yè)務(wù)復(fù)雜,且需要調(diào)用多個(gè)接口

如接口A調(diào)用完后得到的數(shù)據(jù)A需要進(jìn)行拼接,從而構(gòu)造成接口B的參數(shù),去請(qǐng)求接口B得到數(shù)據(jù),那么就得在里面瘋狂套娃,難管理且閱讀很難受

而采用協(xié)程,則將異步操作變?yōu)橥讲僮?如下圖:

Kotlin 協(xié)程基礎(chǔ)使用學(xué)習(xí)

需要注意的是,并不是說協(xié)程比線程池進(jìn)行并發(fā)任務(wù)性能更好,實(shí)際上協(xié)程內(nèi)部還是使用線程調(diào)度的那一套,只不過對(duì)于開發(fā)者來說,更是黑箱操作

只是對(duì)于客戶端開發(fā)來說,可以從那種回調(diào)處理更新UI的解放出來

從性能上去看:

協(xié)程的性能并不優(yōu)于線程池或者其他異步框架,主要是其做了更多語言級(jí)別步驟,但通常情況下,與其他框架的性能幾乎一致,因?yàn)橄啾菼O的耗時(shí),語言級(jí)別的損耗可以幾乎忽略不計(jì);

從設(shè)計(jì)模式去看:

協(xié)程使得開發(fā)者可以自行管理異步任務(wù),而不同于線程的搶占式任務(wù),并且寫成還支持子協(xié)程的嵌套關(guān)閉、更簡(jiǎn)便的異常處理機(jī)制等,故相比其他異步框架,協(xié)程的理念更加先進(jìn);

入門使用

依賴說明

kotlin的協(xié)程是一個(gè)單獨(dú)的庫,需要我們進(jìn)行依賴后才能使用

這里需要說明一下,協(xié)程分為了幾個(gè)Module,需要根據(jù)情況引用(我這里只介紹其中幾個(gè)常用的模塊,需要了解更多可以去看官方文檔說明)

  • kotlinx-coroutines-core
  • kotlinx-coroutines-core-jvm
  • kotlinx-coroutines-android
  • kotlinx-coroutines-javafx

kotlinx-coroutines-core模塊是針對(duì)多平臺(tái)項(xiàng)目一個(gè)公共庫,Kotlin/Native、Kotlin/JVM 和 Kotlin/JS 上使用。

kotlinx-coroutines-core-jvm是專門為在 JVM 平臺(tái)上運(yùn)行的項(xiàng)目設(shè)計(jì),并提供了一些額外的功能,比如提供針對(duì) JVM 的調(diào)度器和擴(kuò)展函數(shù)。

kotlinx-coroutines-androidkotlinx-coroutines-javafx則是針對(duì)的特定的UI平臺(tái),提供了對(duì)應(yīng)的調(diào)度器,Android是Dispatcher.Main,JavaFx則是Dispatch.JavaFx(實(shí)際上也能用Dispatch.Main,與Dispatch.JavaFx等同的)

PS: 這里如果不懂Dispatchers,沒有關(guān)系,只需要記住這個(gè)就是方便我們切換到UI線程(主線程)操作即可

像我一般是在Android平臺(tái)或者是JavaFx平臺(tái),沒有JS和Native的需求

所以一般引用kotlinx-coroutines-core-jvm即可,會(huì)自動(dòng)將kotlinx-coroutines-core也引入

之后根據(jù)平臺(tái)選擇kotlinx-coroutines-androidkotlinx-coroutines-javafx依賴

引入依賴(示例):

<dependency>
    <groupId>org.jetbrains.kotlinx</groupId>
    <artifactId>kotlinx-coroutines-core-jvm</artifactId>
    <version>1.8.0-RC2</version>
</dependency>

//這里省略了對(duì)應(yīng)平臺(tái)的版本依賴,參考下面gradle依賴即可

gradle引入:

implementation ("org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.0-RC2")


//對(duì)應(yīng)平臺(tái)版本依賴,版本是一致的,如果想要切換到主線程來更新UI操作,就需要下面的依賴
//android
implementation ("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.0-RC2")

//javafx
implementation ("org.jetbrains.kotlinx:kotlinx-coroutines-javafx:1.8.0-RC2")

//注意還得加入插件
plugins {
    // For build.gradle.kts (Kotlin DSL)
    kotlin("jvm") version "1.9.21"
    
    // For build.gradle (Groovy DSL)
    id "org.jetbrains.kotlin.jvm" version "1.9.21"
}

不過需要注意的是,上面的版本僅供參考

因?yàn)閰f(xié)程依賴與kotlin版本有關(guān)聯(lián)關(guān)系,如果你使用協(xié)程庫的高版本,可能kotlin也要使用較高版本,不然可能編譯會(huì)報(bào)錯(cuò)

對(duì)于maven項(xiàng)目,修改項(xiàng)目使用的kotlin版本即可

對(duì)于gradle項(xiàng)目,除了修改kotlin版本,還得修改上面的那個(gè)plugin插件版本

不過穩(wěn)妥的做法,還是根據(jù)kotlin版本選擇對(duì)應(yīng)的協(xié)程版本,畢竟沒準(zhǔn)kotlin版本一升級(jí),整個(gè)項(xiàng)目就跑不起來,尤其是Android項(xiàng)目(kotlin版本依賴比較嚴(yán)重)

協(xié)程與kotlin版本對(duì)應(yīng)關(guān)系見下表(點(diǎn)擊展開)
發(fā)布時(shí)間 kotlin版本 官方推薦的協(xié)程庫版本 標(biāo)準(zhǔn)庫更新版本簡(jiǎn)述
2020-04-15 1.3.72 1.3.8 Kotlin 1.3.70 的錯(cuò)誤修復(fù)版本。
2020-08-17 1.4.0 1.3.9 具有許多功能和改進(jìn)的功能版本,主要關(guān)注質(zhì)量和性能。
2020-09-07 1.4.10 1.3.9 Kotlin 1.4.0 的錯(cuò)誤修復(fù)版本。
2020-11-23 1.4.20 1.4.1 支持新的 JVM 功能,例如通過調(diào)用動(dòng)態(tài)進(jìn)行字符串連接,改進(jìn)了 KMM 項(xiàng)目的性能和異常處理,DK 路徑的擴(kuò)展:Path(“dir”) / “file.txt”
2020-12-07 1.4.21 1.4.1 Kotlin 1.4.20 的錯(cuò)誤修復(fù)版本
2021-02-03 1.4.30 1.4.2 新的 JVM 后端,現(xiàn)在處于 Beta 版;新語言功能預(yù)覽;改進(jìn)的 Kotlin/Native 性能;標(biāo)準(zhǔn)庫 API 改進(jìn)
2021-02-25 1.4.31 1.4.2 Kotlin 1.4.30 的錯(cuò)誤修復(fù)版本
2021-03-22 1.4.32 1.4.3 Kotlin 1.4.30 的錯(cuò)誤修復(fù)版本
2021-05-05 1.5.0 1.5.0-RC 具有新語言功能、性能改進(jìn)和進(jìn)化性更改(例如穩(wěn)定實(shí)驗(yàn)性 API)的功能版本。
2021-05-24 1.5.10 1.5.0 Kotlin 1.5.0 的錯(cuò)誤修復(fù)版本。
2021-06-24 1.5.20 1.5.0 默認(rèn)情況下,通過 JVM 上的調(diào)用動(dòng)態(tài)進(jìn)行字符串連接;改進(jìn)了對(duì) Lombok 的支持和對(duì) JSpecify 的支持;Kotlin/Native:KDoc 導(dǎo)出到 Objective-C 頭文件和更快的 Array.copyInto() 在一個(gè)數(shù)組中;Gradle:緩存注解處理器的類加載器并支持 --parallel Gradle 屬性;跨平臺(tái)的 stdlib 函數(shù)的對(duì)齊行為
2021-07-13 1.5.21 1.5.0 Kotlin 1.5.20 的錯(cuò)誤修復(fù)版本。
2021-08-23 1.5.30 1.5.1 JVM上注解類的實(shí)例化;改進(jìn)的選擇加入要求機(jī)制和類型推斷;測(cè)試版中的 Kotlin/JS IR 后端;支持 Apple Silicon 目標(biāo);改進(jìn)的 CocoaPods 支持;Gradle:Java 工具鏈支持和改進(jìn)的守護(hù)程序配置;
2021-09-20 1.5.31 1.5.2 Kotlin 1.5.30 的錯(cuò)誤修復(fù)版本。
2021-11-29 1.5.32 1.5.2 Kotlin 1.5.31 的錯(cuò)誤修復(fù)版本。
2021-11-16 1.6.0 1.6.0 具有新語言功能、性能改進(jìn)和進(jìn)化性更改(例如穩(wěn)定實(shí)驗(yàn)性 API)的功能版本。
2021-12-14 1.6.10 1.6.0 Kotlin 1.6.0 的錯(cuò)誤修復(fù)版本。
2022-04-04 1.6.20 1.6.0 具有各種改進(jìn)的增量版本
2022-04-20 1.6.21 1.6.0 Kotlin 1.6.20 的錯(cuò)誤修復(fù)版本。
2022-06-09 1.7.0 1.7.0 在 Alpha for JVM 中發(fā)布了 Kotlin K2 編譯器的功能、穩(wěn)定的語言功能、性能改進(jìn)和演進(jìn)性變化,例如穩(wěn)定實(shí)驗(yàn)性 API。
2022-07-07 1.7.10 1.7.0 Kotlin 1.7.0 的錯(cuò)誤修復(fù)版本。
2022-09-29 1.7.20 1.7.0 具有新語言功能的增量版本,支持 Kotlin K2 編譯器中的多個(gè)編譯器插件,默認(rèn)啟用新的 Kotlin/Native 內(nèi)存管理器,以及對(duì) Gradle 7.1 的支持。
2022-11-09 1.7.21 1.7.0 Kotlin 1.7.20 的錯(cuò)誤修復(fù)版本。
2022-12-28 1.8.0 1.7.0 一個(gè)功能版本,改進(jìn)了 kotlin-reflect 性能、新的 JVM 遞歸復(fù)制或刪除目錄內(nèi)容實(shí)驗(yàn)功能、改進(jìn)了 Objective-C/Swift 互操作性。
2023-02-02 1.8.10 1.7.0 Kotlin 1.8.0 的錯(cuò)誤修復(fù)版本。
2023-04-03 1.8.20 1.7.0 功能發(fā)布,包括 Kotlin K2 編譯器更新、AutoCloseable 接口和 stdlib 中的 Base64 編碼、默認(rèn)啟用的新 JVM 增量編譯、新的 Kotlin/Wasm 編譯器后端。
2023-04-25 1.8.21 1.7.0 Kotlin 1.8.20 的錯(cuò)誤修復(fù)版本。
2023-06-08 1.8.22 1.7.0 Kotlin 1.8.20 的錯(cuò)誤修復(fù)版本。
2023-07-06 1.9.0 1.7.0 包含 Kotlin K2 編譯器更新的功能版本、新的枚舉類值函數(shù)、開放式范圍的新運(yùn)算符、Kotlin Multiplatform 中的 Gradle 配置緩存預(yù)覽、Kotlin Multiplatform 中的 Android 目標(biāo)支持更改、Kotlin/Native 中的自定義內(nèi)存分配器預(yù)覽 。

摘自:kotlin標(biāo)準(zhǔn)庫與kotlin協(xié)程相關(guān)支持庫對(duì)應(yīng)關(guān)系(持續(xù)更新。。。)_kotlinx-coroutines-core和kotlin-gradle-plugin版本對(duì)應(yīng)-CSDN博客

協(xié)程啟動(dòng)

先來一段協(xié)程啟動(dòng)的代碼

fun main() {
    runBlocking {
        val scope = this
		//啟動(dòng)協(xié)程
        val job = scope.launch(Dispatchers.IO) {
            delay(1000)
            println("延遲1s后打印")
        }
        println("已啟動(dòng)協(xié)程了")
    }
}

運(yùn)行結(jié)果:

已啟動(dòng)協(xié)程了
延遲1s后打印

協(xié)程取消

fun main() {
    runBlocking {
        val scope = this
        val job = scope.launch(Dispatchers.IO) {
            delay(1000)
            println("延遲1s后打印")
        }
        println("已啟動(dòng)協(xié)程了")
		job.cancel()
		println("已取消協(xié)程")
    }
}

基礎(chǔ)概念

協(xié)程主要包含以下部分:

  • 協(xié)程Job:協(xié)程Job是協(xié)程的執(zhí)行單元,它表示了一個(gè)協(xié)程的任務(wù)。我們可以通過Job來控制協(xié)程的啟動(dòng)、取消、等待和異常處理等操作。
  • 協(xié)程構(gòu)建器(Coroutine Builders):協(xié)程構(gòu)建器是創(chuàng)建協(xié)程的入口點(diǎn)。在Kotlin中,常見的協(xié)程構(gòu)建器有launch、async、runBlocking等。
  • 協(xié)程作用域(Coroutine Scope):協(xié)程作用域是協(xié)程的生命周期范圍。它定義了協(xié)程的生命周期和取消操作。通常,我們會(huì)使用GlobalScopeCoroutineScope等來創(chuàng)建協(xié)程作用域。
  • 協(xié)程執(zhí)行器(Dispatcher):協(xié)程執(zhí)行器(也稱為調(diào)度器)是協(xié)程的執(zhí)行線程(或線程池)。它決定了協(xié)程在哪個(gè)線程上執(zhí)行,可以通過指定不同的調(diào)度器來實(shí)現(xiàn)協(xié)程的并發(fā)和異步操作。
  • 協(xié)程掛起函數(shù)(Suspending Function):協(xié)程掛起函數(shù)是在協(xié)程中使用的特殊函數(shù),它可以暫時(shí)掛起協(xié)程的執(zhí)行而不阻塞線程。掛起函數(shù)使用suspend修飾符,并可調(diào)用其他掛起函數(shù)、阻塞函數(shù)、異步函數(shù)等。
  • 協(xié)程上下文(Coroutine Context):協(xié)程上下文是協(xié)程的運(yùn)行環(huán)境,包含了協(xié)程的調(diào)度器(Dispatcher)和其他上下文元素,如異常處理器等。協(xié)程上下文可以由調(diào)度器、Job、異常處理器等元素組成。

其實(shí)入門的簡(jiǎn)單使用,用的比較頻繁的還是前5個(gè)概念,最后一個(gè)協(xié)程上下文概念我可能不會(huì)花太多筆墨寫

協(xié)程上下文CoroutineContext實(shí)際是一個(gè)接口,而Job,Dispatcher都是實(shí)現(xiàn)了協(xié)程上下文此接口

首先,要有個(gè)概念,只要在協(xié)程作用域中才能啟動(dòng)協(xié)程,而協(xié)程作用域,需要通過協(xié)程構(gòu)建器來進(jìn)行創(chuàng)建

我們來看上面的代碼

fun main() {
	//runBlocking方法實(shí)際上就是協(xié)程構(gòu)建器
    runBlocking {
		//這里的作用域?qū)嶋H就是協(xié)程作用域
        val scope = this
		//通過launch方法來啟動(dòng)一個(gè)協(xié)程,得到一個(gè)Job對(duì)象
		//實(shí)際上,把Job對(duì)象說成協(xié)程應(yīng)該就好理解了
		//注意這里,出現(xiàn)了一個(gè)Dispatchers.IO,這個(gè)就是我們的協(xié)程執(zhí)行器,可以看做為一個(gè)協(xié)程提供的線程池(之后會(huì)細(xì)講)
        val job = scope.launch(Dispatchers.IO) {
			//delay是延遲執(zhí)行,是協(xié)程作用域提供的一個(gè)方法
            delay(1000)
            println("延遲1s后打印")
        }
        println("已啟動(dòng)協(xié)程了")
    }
}

通過上面的代碼,應(yīng)該對(duì)前4個(gè)概念有些基本了解了,再來說說掛起函數(shù)

以上面代碼為例,協(xié)程里的方法太多了,想要封裝成一個(gè)方法,可以這樣改造:

fun main() {
    runBlocking {
        val scope = this
        val job = scope.launch(Dispatchers.IO) {
           test()
        }
        println("已啟動(dòng)協(xié)程了")
    }

}

suspend fun test() {
    delay(1000)
    println("延遲1s后打印")
}

由于我們因?yàn)橛玫搅薲elay這個(gè)方法,所以我們得將當(dāng)前方法加上一個(gè)suspend關(guān)鍵字,聲明當(dāng)前函數(shù)是掛起函數(shù)

只有聲明了我們才能在函數(shù)里使用delay這個(gè)方法,不加關(guān)鍵字,IDE會(huì)提示行代碼標(biāo)紅,無法通過編譯

同時(shí),還有一個(gè)概念,只有在協(xié)程作用域上,才能調(diào)用掛起函數(shù)

當(dāng)然,如果你的方法里沒有delay此類方法,可以不加suspend關(guān)鍵字聲明

協(xié)程作用域提供了不止delay這個(gè)方法,還有些其他方法,下文會(huì)進(jìn)行補(bǔ)充

至于最后一個(gè)協(xié)程上下文,我們可以runBlocking和launch方法參數(shù)見到它的身影如下圖:

Kotlin 協(xié)程基礎(chǔ)使用學(xué)習(xí)

由于本文偏向使用為主,所以不打算對(duì)協(xié)程上下文進(jìn)行展開細(xì)說了

協(xié)程構(gòu)建器

前面也說到了,runBlocking()可以看做為一個(gè)協(xié)程構(gòu)建器,但這個(gè)只是方便我們?cè)趍ain方法或者測(cè)試使用,為什么呢?

因?yàn)樗鼘?shí)際上會(huì)阻塞當(dāng)前線程,如下代碼:

fun main() {
    runBlocking() {
        val scope = this
        val job = scope.launch(Dispatchers.IO) {
           delay(1000)
           println("延遲1s后打印")
        }
        println("已啟動(dòng)協(xié)程了")
    }
    println("任務(wù)結(jié)束")
}

輸出結(jié)果:

已啟動(dòng)協(xié)程了
延遲1s后打印
任務(wù)結(jié)束

由輸出結(jié)果可以看出,當(dāng)前main方法需要等待runBlocking()方法及里面協(xié)程執(zhí)行完畢才會(huì)執(zhí)行完畢

但是像Android開發(fā)和Javafx開發(fā),如果想上述這樣寫法,在runBlocking()進(jìn)行耗時(shí)長的任務(wù),那么估計(jì)UI線程直接卡死,Android直接出現(xiàn)ANR異常了

那么問題來了,協(xié)程提供了哪些協(xié)程構(gòu)造器?

答案如下:

  • runBlocking
  • launch
  • async

runBlocking: 會(huì)創(chuàng)建一個(gè)新的協(xié)程同時(shí)阻塞當(dāng)前線程,直到協(xié)程結(jié)束。適用于main函數(shù)和單元測(cè)試

需要注意的是,runBlocking會(huì)根據(jù)最后一行從而返回?cái)?shù)值,類似kotlin對(duì)象的run函數(shù),如

fun main() {
    val str = runBlocking() {
		//省略協(xié)程啟動(dòng)等操作
        "hello"
    }
	//返回字符串
    println(str)
}

launch : 創(chuàng)建一個(gè)新的協(xié)程,不會(huì)阻塞當(dāng)前線程,必須在協(xié)程作用域中才可以調(diào)用。它返回的是一個(gè)該協(xié)程任務(wù)的引用,即Job對(duì)象。這是最常用的啟動(dòng)協(xié)程的方式。

async: 創(chuàng)建一個(gè)新的協(xié)程,不會(huì)阻塞當(dāng)前線程,必須在協(xié)程作用域中才可以調(diào)用,并返回Deffer對(duì)象。可通過調(diào)用Deffer.await()方法等待該子協(xié)程執(zhí)行完成并獲取結(jié)果。常用于并發(fā)執(zhí)行-同步等待和獲取返回值的情況。

由于launchasync2個(gè)構(gòu)造器得需要和協(xié)程作用域配合使用,所以決定在下面和協(xié)程作用域一起講解了

協(xié)程和協(xié)程作用域

協(xié)程作用域

如果在一段普通代碼想要開啟協(xié)程,除了上面說到的runBlocking方法,我們還可以通過協(xié)程作用域來調(diào)用launchasync來進(jìn)行協(xié)程的啟動(dòng)

可用的協(xié)程作用域有:

  • GlobalScope
  • CoroutineScope
  • supervisorScope{} 好像低版本只有方法,而高版本的協(xié)程庫則可以使用類SupervisorScope
  • MainScope 主線程協(xié)程作用域(需要引用對(duì)應(yīng)平臺(tái)的依賴,如android或javafx才會(huì)有此作用域)

其中GlobalScope是一個(gè)全局的協(xié)程作用域?qū)ο?使用的話,直接使用靜態(tài)方法來進(jìn)行,如下代碼:

GlobalScope.launch { 
	//你的邏輯
}

不過這種啟動(dòng)的協(xié)程存在組件被銷毀但協(xié)程還存在的情況,一般不推薦

而一般推薦使用新建一個(gè)CoroutineScope對(duì)象來啟動(dòng)協(xié)程,之后在組件銷毀的生命周期手動(dòng)調(diào)用cancel()方法,會(huì)將當(dāng)前所有的協(xié)程任務(wù)都取消,如下代碼:


//在當(dāng)前類聲明此對(duì)應(yīng)(如Activity)
val scope = CoroutineScope(Dispatchers.Main)

//這里在按鈕點(diǎn)擊事件里執(zhí)行
//這里使用的協(xié)程調(diào)度器指定當(dāng)前協(xié)程作用域是在主線程(UI線程)
scope.launch{
	
}

//在組件銷毀的生命周期(如Activity的onDestroy方法里)
scope.cancel()

SupervisorScope這個(gè)協(xié)程作用域主要是針對(duì)異常的,如果子協(xié)程發(fā)生異常,則不影響父協(xié)程的運(yùn)行(具體可見下文的"協(xié)程里的異常"一章),這里先不介紹

MainScope主要是UI主線程的協(xié)程作用域,在此作用域,相當(dāng)于在主線程操作,一般我們將耗時(shí)操作切換到Dispatchers.IO去做,如下代碼:

MainScope().launch{
	withContext(Dispatchers.IO){
		//網(wǎng)絡(luò)請(qǐng)求等耗時(shí)操作
	}
	//更新UI操作
}

上面的withContext()方法也是在協(xié)程作用域才能使用的方法,目的就是切換到其他協(xié)程執(zhí)行耗時(shí)操作,執(zhí)行完畢后再切換回當(dāng)前的協(xié)程(主線程),是個(gè)阻塞操作

如果需要根據(jù)網(wǎng)絡(luò)請(qǐng)求的結(jié)果從而來進(jìn)行更新UI,可以利用withContext()的返回值,如將上述代碼改造如下:

MainScope().launch{
	val str = withContext(Dispatchers.IO){
		//網(wǎng)絡(luò)請(qǐng)求等耗時(shí)操作
		//假設(shè)得到一個(gè)字符串返回值
		"hello"
	}
	//更新UI操作
	tv.text = str
}

PS:如果對(duì)于Android平臺(tái),還可以使用下面的2個(gè)作用域:

  • lifecycleScope:生命周期范圍,用于activity等有生命周期的組件,在DESTROYED的時(shí)候會(huì)自動(dòng)結(jié)束,需要導(dǎo)入依賴implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.2.0'
  • viewModelScope:viewModel范圍,用于ViewModel中,在ViewModel被回收時(shí)會(huì)自動(dòng)結(jié)束,需要導(dǎo)入依賴implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0'

介紹完上面幾個(gè)協(xié)程作用域后,接下來對(duì)launch方法和async方法進(jìn)行講解

調(diào)度器

在講解launch方法之前,先講解下調(diào)度器的種類和概念

首先,我們知道此launch方法返回job對(duì)象,之后我們可以對(duì)job對(duì)象操作,調(diào)用job.cancel()取消任務(wù)

而launch方法里的傳參,可以傳遞一個(gè)調(diào)度器,那么協(xié)程中有哪幾個(gè)調(diào)度器?

主要有以下幾個(gè):

  • Dispatchers.DEFAULT
  • Dispatchers.IO
  • Dispatchers.MAIN

簡(jiǎn)單理解調(diào)度器視為線程就比較好理解了,比如說我們需要執(zhí)行長時(shí)間的任務(wù),就使用Dispatchers.IO調(diào)度器,而需要更改UI,則切換回主線程,如下面代碼示例:

btn.setOnClicker{
	//按鈕點(diǎn)擊觸發(fā)協(xié)程
	val job = CoroutineScope(Dispatchers.Main).launch(Dispatchers.Main){
		val result = withContext(Dispatchers.IO){
			//模擬請(qǐng)求數(shù)據(jù),最終得到數(shù)據(jù)
			"resp"
		}
		//根據(jù)result來進(jìn)行更改UI操作(這里已經(jīng)在主線程了)
		textview.text = "result"
	}
}

就像之前所說,我們?cè)谄胀ùa中使用launch,就得先創(chuàng)建一個(gè)協(xié)程作用域CoroutineScope,之后再啟動(dòng)一個(gè)協(xié)程

CoroutineScope的構(gòu)造方法需要傳一個(gè)協(xié)程調(diào)度器,這里我們就是傳了Dispatchers.MAIN,標(biāo)示此協(xié)程作用域默認(rèn)是在主線程

之后我們也可以通過launch方法來切換不同的線程執(zhí)行,上面代碼中,CoroutineScope和launch都有設(shè)置一個(gè)調(diào)度器

實(shí)際上,Dispatchers.MAIN是一個(gè)對(duì)象,上面代碼我們可以省略launch方法里參數(shù),如下代碼

btn.setOnClicker{
	//按鈕點(diǎn)擊觸發(fā)協(xié)程
	val job = CoroutineScope(Dispatchers.Main).launch{
		val result = withContext(Dispatchers.IO){
			//模擬請(qǐng)求數(shù)據(jù),最終得到數(shù)據(jù)
			"resp"
		}
		//根據(jù)result來進(jìn)行更改UI操作(這里已經(jīng)在主線程了)
		textview.text = "result"
	}
}

如果引用了Javafx的依賴,那么這個(gè)Dispatchers.MAINDispatchers.JAVAFX是一個(gè)對(duì)象,兩者可互用

再來說說Dispatchers.IO,實(shí)際上這個(gè)是類似線程池的東西,創(chuàng)建的協(xié)程任務(wù)可能會(huì)被分配到不同的協(xié)程上去執(zhí)行

協(xié)程實(shí)際也有有個(gè)線程池的,只不過我們使用可以不太關(guān)心,當(dāng)然,如果你需要自己構(gòu)建一個(gè)線程池給協(xié)程使用,也有對(duì)應(yīng)方法可以設(shè)置,如下方法

// 創(chuàng)建一個(gè)包含多個(gè)線程的線程池
val customThreadPool = Executors.newFixedThreadPool(4).asCoroutineDispatcher()

runBlocking {
	//啟動(dòng)的設(shè)置
	launch(customThreadPool) { 
		 
	}
	//或者
	withContext(customThreadPool) {
		repeat(10) {
			println("Coroutine is running on thread: ${Thread.currentThread().name}")
		}
	}
}

// 關(guān)閉線程池
(customThreadPool.executor as? Executors)?.shutdown()

asCoroutineDispatcher()方法,是協(xié)程為傳統(tǒng)線程池提供的一個(gè)擴(kuò)展方法,可以將線程池轉(zhuǎn)為我們的Dispatcher進(jìn)行使用(用法方面,和Dispatchers.Main這種對(duì)象使用一樣)

launch方法

其實(shí)關(guān)于launch()的使用方法,上面的例子已經(jīng)介紹的七七八八了,主要是對(duì)關(guān)于launch()返回的Job對(duì)象進(jìn)行講解

Job對(duì)象有以下常用屬性和方法:

  • isActive 當(dāng)前協(xié)程是否已經(jīng)激活

  • isCompleted 當(dāng)前協(xié)程是否已經(jīng)完成

  • isCancelled 當(dāng)前協(xié)程是否已經(jīng)取消

  • cancel() 用于Job的取消,取消協(xié)程

  • start() 用于啟動(dòng)一個(gè)協(xié)程,讓其到達(dá)Active狀態(tài)

  • invokeOnCompletion() 當(dāng)其完成或者異常時(shí)會(huì)調(diào)用

  • join() 阻塞并等候當(dāng)前協(xié)程完成

前3個(gè)屬性很好理解,這里直接跳過;

注意到有一個(gè)start()方法,什么意思呢?因?yàn)閰f(xié)程可以設(shè)置為懶啟動(dòng),具體代碼如下:

val job = launch(start = CoroutineStart.LAZY) {  }
job.start()

而關(guān)于CoroutineStart類,有以下幾種選中

  • DEFAULT:默認(rèn)啟動(dòng)模式,表示協(xié)程會(huì)立即開始執(zhí)行。(之前省略不寫,就是使用的這個(gè)選項(xiàng))
  • LAZY:懶啟動(dòng)模式,表示協(xié)程只有在首次被使用時(shí)才會(huì)啟動(dòng)執(zhí)行。
  • ATOMIC:原子啟動(dòng)模式,表示協(xié)程會(huì)盡快被執(zhí)行,但可以被取消。
  • UNDISPATCHED:未調(diào)度啟動(dòng)模式,表示協(xié)程會(huì)在當(dāng)前調(diào)用者線程中立即執(zhí)行,而不進(jìn)行調(diào)度。

至于后2種,目前我沒有在具體情景使用,只是做個(gè)了解,不擴(kuò)展進(jìn)行說明了

invokeOnCompletion方法則是方便我們監(jiān)聽協(xié)程完成后的操作,具體示例代碼如下:

val job = launch() {  }
job.invokeOnCompletion{
	//相關(guān)邏輯
}

這里通過IDE的代碼提示,可以看見invokeOnCompletion方法還可以接受2個(gè)參數(shù)

  • onCancelling job被取消是否觸發(fā)當(dāng)前回調(diào),默認(rèn)為false
  • invokeImmediately 指示指定的代碼塊是否應(yīng)立即調(diào)用,而不管作業(yè)狀態(tài)如何,默認(rèn)為true

上面列的幾個(gè)方法只是常用的,還有些不常用的方法,由于自己不怎么常用,這里就不一一來列出來了

協(xié)程并發(fā)

async方法

如果說,我們想要實(shí)現(xiàn)幾個(gè)協(xié)程并發(fā)進(jìn)行,就可以使用此方法來開啟多個(gè)協(xié)程,如下例子

runBlocking {
	async() {
		//邏輯1
	}
	async() {
		//邏輯2
	}
}

async方法參數(shù)和launch方法是一樣的,用法方面我這里就不多說什么了,唯一需要注意的是,async方法返回的是一個(gè)Deffer對(duì)象(雖然它也是繼承于Job對(duì)象)

如果我們需要等待某個(gè)方法的結(jié)果的話,可以使用Deffer.await()方法來實(shí)現(xiàn),如下面例子:

runBlocking {
	val deffer = async {
		delay(200)
		5 //這里語法上是kotlin的作用域方法,返回一個(gè)int類型,如果不明白的可以自行去了解下
	}
   val result = deffer.await() // result為Int類型,數(shù)據(jù)為5
}

await()調(diào)用后,會(huì)使當(dāng)前協(xié)程作用域進(jìn)行等待,直到協(xié)程執(zhí)行完畢

由于Deffer對(duì)象是繼承于Job對(duì)象,所有Job的相關(guān)方法,它也可以用,這里參考上面說到的Job的相關(guān)方法即可

最后補(bǔ)充下:

如果我們需要協(xié)程并發(fā)比較多的話,可以使用一個(gè)list來裝Deffer對(duì)象,最后統(tǒng)一調(diào)用await()方法,代碼如下:

runBlocking {

	val list = (0..10).map {
		async {
			delay(200)
			5
		}
	}
	
	list.forEach { 
		//每個(gè)協(xié)程執(zhí)行結(jié)果,做對(duì)應(yīng)邏輯操作
		val result = it.await()
	}
}

不過看到某大佬的文章,提到:協(xié)程并發(fā)并不是指線程并發(fā),

上面代碼實(shí)際也可以使用launch方法來實(shí)現(xiàn)并發(fā),詳見此文Kotlin協(xié)程-協(xié)程的日常進(jìn)階使用 - 掘金

父協(xié)程和子協(xié)程

還記得上面提到的協(xié)程取消方法嗎?協(xié)程取消,會(huì)同時(shí)將其有關(guān)聯(lián)的子協(xié)程全部依次取消,具體代碼:

runBlocking {
	val job1 = launch {
		val deffer = async {
		}

		val job2 = launch {  }
	}
	job1.cancel()
}

如上面示例,job1為父協(xié)程,deffer和job2為子協(xié)程,當(dāng)父協(xié)程取消,同時(shí)deffer和job2也會(huì)取消

這里還有一點(diǎn)要說明:

協(xié)程的異常是會(huì)傳遞的,比如當(dāng)一個(gè)子協(xié)程發(fā)生異常時(shí),它會(huì)影響它的兄弟協(xié)程與它的父協(xié)程。而使用了 SupervisorJob() 則意味著,其子協(xié)程的異常都將由其自己處理,而不會(huì)向外擴(kuò)散,影響其他協(xié)程。

詳情文章解釋可參考此文Kotlin | 關(guān)于協(xié)程異常處理,你想知道的都在這里 - 掘金,本文不擴(kuò)展說明了

一般這樣定義一個(gè)作用域即可解決問題,代碼如下:

private val exceHandler = CoroutineExceptionHandler { coroutineContext, throwable ->
    Log.e("tttt", "協(xié)程發(fā)生異常", throwable)
}
//調(diào)度器Dispatchers.IO根據(jù)你自己需要來即可
val gCo = CoroutineScope(SupervisorJob() + Dispatchers.IO + exceHandler)

擴(kuò)展補(bǔ)充

傳統(tǒng)java接口回調(diào)如何轉(zhuǎn)協(xié)程同步寫法

之前一直有個(gè)痛點(diǎn),就是用的是Java庫,里面提供的異步操作結(jié)果都是通過接口回調(diào)的方式來返回?cái)?shù)據(jù)的,如果我們kotlin中也是去這樣寫的話,根本就沒法體驗(yàn)到協(xié)程的優(yōu)勢(shì)

kotlin協(xié)程,則是提供了一個(gè)高級(jí)函數(shù)suspendCancellableCoroutine{}供我們解決上述問題

這里以一個(gè)簡(jiǎn)單的網(wǎng)絡(luò)請(qǐng)求為例,有2個(gè)接口回調(diào),分別代表請(qǐng)求成功和請(qǐng)求失敗

interface RespInterface {
	fun onSuccess(data:String)

	fun onError()
}

Net.post(object :RespInterface{
	override fun onSuccess(data: String) {
	}

	override fun onError() {
	}
})

使用suspendCancellableCoroutine{}改造,代碼:

suspend fun myJob() = suspendCancellableCoroutine<String> {
	//下面的it代表CancellableContinuation<String>對(duì)象
	Net.post(object :RespInterface{
		override fun onSuccess(data: String) {
			it.resume(data){}
		}

		override fun onError() {
			it.resume(""){}
		}
	})
}

//在協(xié)程中調(diào)用
runBlocking {
	//result為對(duì)應(yīng)的返回結(jié)果
	val result = postNet()
}

suspendCancellableCoroutine{}返回的是CancellableContinuation對(duì)象,這里的T類型,就是看你最終調(diào)用resume方法返回的對(duì)象類型來定義

上面我只是一個(gè)簡(jiǎn)單的例子,如果請(qǐng)求失敗,則返回一個(gè)空白字符串,到時(shí)候邏輯在協(xié)程里判斷即可

對(duì)話框按順序彈出(Android)

這個(gè)同理,也是根據(jù)上面的suspendCancellableCoroutine{}方法來實(shí)現(xiàn)的,就是有點(diǎn)麻煩,得每個(gè)對(duì)話框的方法都單獨(dú)寫

下面代碼是在Android平臺(tái)上使用的,使用DialogX庫的里的提示框作為示例:

suspend fun showDialog1() = suspendCancellableCoroutine<String> {
	MessageDialog.show("提示1","提示1","確定")
		.setOkButton { dialog, v -> 
			false
		}
		.setDialogLifecycleCallback(object :DialogLifecycleCallback<MessageDialog>(){
			override fun onDismiss(dialog: MessageDialog?) {
				it.resume(""){}
				super.onDismiss(dialog)
			}
		})

}

suspend fun showDialog2() = suspendCancellableCoroutine<String> {
	MessageDialog.show("提示2","提示2","確定")
		.setOkButton { dialog, v ->
			false
		}
		.setDialogLifecycleCallback(object :DialogLifecycleCallback<MessageDialog>(){
			override fun onDismiss(dialog: MessageDialog?) {
				it.resume(""){}
				super.onDismiss(dialog)
			}
		})

}

//使用
lifecycleScope.launch {
	showDialog1()
	showDialog2()
}

如何自定義一個(gè)協(xié)程作用域

可以直接讓我們的類實(shí)現(xiàn) CoroutineScope 接口,但是我們需要指定協(xié)程的上下文,如下面代碼:

/**
 * 自定義帶協(xié)程作用域的彈窗
 */
abstract class CoroutineScopeCenterPopup(activity: FragmentActivity) : CenterPopupView(activity), CoroutineScope {

    private lateinit var job: Job

    private val exceptionHandler = CoroutineExceptionHandler { coroutineContext, throwable ->
        YYLogUtils.e(throwable.message ?: "Unkown Error")
    }

    //此協(xié)程作用域的自定義 CoroutineContext
    override val coroutineContext: CoroutineContext
        get() = Dispatchers.Main + job + CoroutineName("CenterPopupScope") + exceptionHandler


    override fun onCreate() {
        job = Job()
        super.onCreate()
    }


    override fun onDismiss() {
        job.cancel()  // 關(guān)閉彈窗后,結(jié)束所有協(xié)程任務(wù)
        YYLogUtils.w("關(guān)閉彈窗后,結(jié)束所有協(xié)程任務(wù)")
        super.onDismiss()
    }
}

上文代碼摘抄自Kotlin協(xié)程-協(xié)程的日常進(jìn)階使用 - 掘金,僅供記錄方便后來查閱參考

協(xié)程常用高階函數(shù)

協(xié)程里提供了一些函數(shù)使用,上面應(yīng)該已經(jīng)介紹的差不多了文章來源地址http://www.zghlxwxcb.cn/news/detail-841268.html

//創(chuàng)建一個(gè)普通的CoroutineScope
coroutineScope {}

//使用SupervisorJob()創(chuàng)建一個(gè)CoroutineScope
supervisorScope{}

//執(zhí)行一個(gè)掛起函數(shù),如果超時(shí),拋出TimeoutCancellationException異常!
withTimeout(time Millis: 1000){}

//執(zhí)行一個(gè)掛起函數(shù),如果超時(shí),返回null
withTimeoutorNull(time Millis: 1000) {}

//掛起當(dāng)前協(xié)程,直到協(xié)程執(zhí)行完成,如果傳遞的context與當(dāng)前context一致,則該函數(shù)不會(huì)掛起,相當(dāng)于阻塞執(zhí)行
withContext(Dispatchers.I0) {}

//一個(gè)方便的可取消的協(xié)程作用域
suspendCancellableCoroutine{}

參考

  • kotlinx.coroutines/README.md at master · Kotlin/kotlinx.coroutines
  • 協(xié)程基礎(chǔ) · Kotlin 官方文檔 中文版
  • Kotlin | 關(guān)于協(xié)程異常處理,你想知道的都在這里 - 掘金
  • 寫給Android工程師的協(xié)程指南 - 掘金
  • Kotlin協(xié)程解析系列(上):協(xié)程調(diào)度與掛起 - 知乎
  • 如何通過Kotlin協(xié)程, 簡(jiǎn)化"連續(xù)依次彈窗(Dialog隊(duì)列)"的需求 - 掘金
  • Kotlin協(xié)程-CoroutineScope協(xié)程作用域 - 掘金
  • Kotlin協(xié)程-協(xié)程的日常進(jìn)階使用 - 掘金

到了這里,關(guān)于Kotlin 協(xié)程基礎(chǔ)使用學(xué)習(xí)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【28】Kotlin語法進(jìn)階——使用協(xié)程編寫高效的并發(fā)程序

    【28】Kotlin語法進(jìn)階——使用協(xié)程編寫高效的并發(fā)程序

    提示:此文章僅作為本人記錄日常學(xué)習(xí)使用,若有存在錯(cuò)誤或者不嚴(yán)謹(jǐn)?shù)玫胤綒g迎指正。 協(xié)程是Kotlin語言中很有代表性的一種并發(fā)設(shè)計(jì)模式,用于簡(jiǎn)化異步執(zhí)行的代碼。 協(xié)程和線程有點(diǎn)類似,可以簡(jiǎn)單地將它理解成一種輕量級(jí)的線程 。我們前面學(xué)習(xí)的線程是屬于重量級(jí)的,

    2024年02月03日
    瀏覽(27)
  • Android使用kotlin+協(xié)程+room數(shù)據(jù)庫的簡(jiǎn)單應(yīng)用

    Android使用kotlin+協(xié)程+room數(shù)據(jù)庫的簡(jiǎn)單應(yīng)用

    前言:一般主線程(UI線程)中是不能執(zhí)行創(chuàng)建數(shù)據(jù)這些操作的,因?yàn)榈却龝r(shí)間長。所以協(xié)程就是為了解決這個(gè)問題出現(xiàn)。 第一步:在模塊級(jí)的build.gradle中引入 ? 好了前期工作ok,正式編寫room吧! 第二步:創(chuàng)建表實(shí)體 ?第三部:編寫對(duì)應(yīng)的Dao接口 ?第四步:創(chuàng)建數(shù)據(jù)庫信息

    2024年02月13日
    瀏覽(23)
  • 【kotlin 協(xié)程】萬字協(xié)程 一篇完成kotlin 協(xié)程進(jìn)階

    【kotlin 協(xié)程】萬字協(xié)程 一篇完成kotlin 協(xié)程進(jìn)階

    Kotlin 中的協(xié)程提供了一種全新處理并發(fā)的方式,可以在 Android 平臺(tái)上使用它來簡(jiǎn)化異步執(zhí)行的代碼。協(xié)程是從 Kotlin 1.3 版本開始引入,但這一概念在編程世界誕生的黎明之際就有了,最早使用協(xié)程的編程語言可以追溯到 1967 年的 Simula 語言。 在過去幾年間,協(xié)程這個(gè)概念發(fā)展

    2024年02月07日
    瀏覽(37)
  • Kotlin 協(xié)程一 —— 協(xié)程 Coroutine

    1.1.1基本定義 進(jìn)程 進(jìn)程是一個(gè)具有一定獨(dú)立功能的程序在一個(gè)數(shù)據(jù)集上的一次動(dòng)態(tài)執(zhí)行的過程,是操作系統(tǒng)進(jìn)行資源分配和調(diào)度的一個(gè)獨(dú)立單位,是應(yīng)用程序運(yùn)行的載體。 進(jìn)程是資源分配的最小單位,在單核CPU中,同一時(shí)刻只有一個(gè)程序在內(nèi)存中被CPU調(diào)用運(yùn)行。 線程 基本的

    2024年02月05日
    瀏覽(20)
  • Kotlin協(xié)程-從一到多

    上一篇文章,我介紹了Kotlin協(xié)程的創(chuàng)建,使用,協(xié)作等內(nèi)容。本篇將引入更多的使用場(chǎng)景,繼續(xù)帶你走進(jìn)協(xié)程世界。 常用編程語言都會(huì)內(nèi)置對(duì)同一類型不同對(duì)象的數(shù)據(jù)集表示,我們通常稱之為容器類。不同的容器類適用于不同的使用場(chǎng)景。Kotlin的 Flow 就是在異步計(jì)算的需求下

    2024年02月09日
    瀏覽(19)
  • Android Kotlin 協(xié)程初探

    維基百科:協(xié)程,英文Coroutine [k?ru’tin] (可入廳),是計(jì)算機(jī)程序的一類組件,推廣了協(xié)作式多任務(wù)的子程序,允許執(zhí)行被掛起與被恢復(fù)。 作為Google欽定的Android開發(fā)首選語言Kotlin,協(xié)程并不是 Kotlin 提出來的新概念,目前有協(xié)程概念的編程語言有Lua語言、Python語言、Go語言

    2024年02月08日
    瀏覽(27)
  • Kotlin協(xié)程-從理論到實(shí)戰(zhàn)

    上一篇文章從理論上對(duì)Kotlin協(xié)程進(jìn)行了部分說明,本文將在上一篇的基礎(chǔ)上,從實(shí)戰(zhàn)出發(fā),繼續(xù)協(xié)程之旅。 在Kotlin中,要想使用協(xié)程,首先需要使用協(xié)程創(chuàng)建器創(chuàng)建,但還有個(gè)前提——協(xié)程作用域( CoroutineScope )。在早期的Kotlin實(shí)現(xiàn)中,協(xié)程創(chuàng)建器是一等函數(shù),也就是說我們隨

    2024年02月09日
    瀏覽(21)
  • Kotlin協(xié)程學(xué)習(xí)之-02

    協(xié)程的基本使用 GlobalScope.launch 生命周期與進(jìn)程一致,且無法取消 runBlocking 會(huì)阻塞線程,一般在測(cè)試階段可以使用 val coroutineScope = CoroutineScope(context) coroutineScope.launch 通過context參數(shù)去管理和控制協(xié)程的生命周期 用法 val coroutineScope = CoroutineScope(context) coroutineScope.launch(Dispatche

    2024年01月22日
    瀏覽(19)
  • Kotlin 協(xié)程 - 多路復(fù)用 select()

    ? ? ? ? 又叫選擇表達(dá)式,是一個(gè)掛起函數(shù),可以同時(shí)等待多個(gè)掛起結(jié)果,只取用最快恢復(fù)的那個(gè)值(即多種方式獲取數(shù)據(jù),哪個(gè)更快返回結(jié)果就用哪個(gè))。 ????????同時(shí)到達(dá) select() 會(huì)優(yōu)先選擇先寫子表達(dá)式,想隨機(jī)(公平)的話使用 selectUnbiased() 替換?。 ????????能

    2024年02月10日
    瀏覽(29)
  • 協(xié)程 VS 線程,Kotlin技術(shù)精講

    協(xié)程 VS 線程,Kotlin技術(shù)精講

    協(xié)程(coroutines)是一種并發(fā)設(shè)計(jì)模式,您可以在Android 平臺(tái)上使用它來簡(jiǎn)化異步執(zhí)行的代碼。協(xié)程是在版本 1.3 中添加到 Kotlin 的,它基于來自其他語言的既定概念。 在 Android 上,協(xié)程有助于管理長時(shí)間運(yùn)行的任務(wù),如果管理不當(dāng),這些任務(wù)可能會(huì)阻塞主線程并導(dǎo)致應(yīng)用無響應(yīng)。

    2024年02月09日
    瀏覽(22)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包