Coroutine 協(xié)程

一、協(xié)程概念

協(xié)程是一種并發(fā)設(shè)計模式,用它來簡化異步執(zhí)行的代碼。
優(yōu)點:

  1. 輕量:協(xié)程可以掛起,比阻塞更省內(nèi)存
  2. 減少內(nèi)存泄漏
  3. 支持取消
  4. 支持Jatpack集成

二、CoroutineScope 協(xié)程作用域

  1. GlobalScope 全局的,一般不會釋放,所以基本不要
  2. MainScope 需要自己 取消
  3. LifecycleScope 不需要關(guān)心取消,自動綁定Lifecycle生命周期了
  4. ViewModelScope 不需要關(guān)心取消,自動綁定ViewModel生命周期了

三、CoroutineScope.launch、CoroutineScope.async

  • 不阻塞線程,在后臺開啟協(xié)程,默認(rèn)立馬執(zhí)行
  • 區(qū)別:launch 返回是Job,async 返回是Deferred<T> ,可以調(diào)用await()等待獲取結(jié)果

四、suspend(掛起) 函數(shù)特點

  • suspend函數(shù),不阻塞線程
  • 必須在協(xié)程或者suspend函數(shù)里面執(zhí)行
  • 要等suspend函數(shù)執(zhí)行完成,代碼才繼續(xù)往下執(zhí)行

五、suspend withContext 、suspend coroutineScope

  • 屬于suspend 函數(shù),不阻塞線程
  • 里面最后一行作為返回值,要等里面的代碼執(zhí)行完成,才繼續(xù)往下執(zhí)行
  • 區(qū)別:withContext可以設(shè)置作用域,coroutineScope不行

六、CoroutineStart - 啟動模式

  1. CoroutineStart.DEFAULT: 協(xié)程創(chuàng)建后,立即開始調(diào)度,但 有可能在執(zhí)行前被取消。在調(diào)度前如果協(xié)程被取消,其將直接進入取消響應(yīng)的狀態(tài)。
  2. CoroutineStart.ATOMIC : 協(xié)程創(chuàng)建后,立即開始調(diào)度, 協(xié)程執(zhí)行到第一個掛起點之前不響應(yīng)取消。其將調(diào)度和執(zhí)行兩個步驟合二為一,就像它的名字一樣,其保證調(diào)度和執(zhí)行是原子操作,因此協(xié)程也 一定會執(zhí)行。
  3. CoroutineStart.LAZY : 只要協(xié)程被需要時(主動調(diào)用該協(xié)程的 start、 join、 await等函數(shù)時 ),才會開始調(diào)度,如果調(diào)度前就被取消,協(xié)程將直接進入異常結(jié)束狀態(tài)。
  4. CoroutineStart.UNDISPATCHED : 協(xié)程創(chuàng)建后,立即在當(dāng)前線程中執(zhí)行,直到遇到第一個真正掛起的點。 是立即執(zhí)行,因此協(xié)程 一定會執(zhí)行

六、Dispatchers - 協(xié)程調(diào)度器

  1. Default: 默認(rèn)調(diào)度器 ,適合處理后臺計算,其是一個 CPU 密集型任務(wù)調(diào)度器
  2. IO: IO 調(diào)度器,適合執(zhí)行 IO 相關(guān)操作,其是 IO 密集型任務(wù)調(diào)度器
  3. Main: UI 調(diào)度器,根據(jù)平臺不同會被初始化為對應(yīng)的 UI 線程的調(diào)度器, 例如在Android 平臺上它會將協(xié)程調(diào)度到 UI 事件循環(huán)中執(zhí)行,即通常在 主線程上執(zhí)行
  4. Unconfined:“無所謂“調(diào)度器,不要求協(xié)程執(zhí)行在特定線程上。協(xié)程的調(diào)度器如果是 Unconfined, 那么它在掛起點恢復(fù)執(zhí)行時會在恢復(fù)所在的線程上直接執(zhí)行,當(dāng)然, 如果嵌套創(chuàng)建以它為調(diào)度器的協(xié)程,那么這些協(xié)程會在啟動時被調(diào)度到協(xié)程框架內(nèi)部的事件循環(huán)上,以避免出現(xiàn) StackOverflow。
七、協(xié)程使用
// 協(xié)程測試類
object CoroutineTest : CoroutineScope by MainScope() { // 代理類實現(xiàn) 協(xié)程作用域
    // 協(xié)程測試
    suspend fun coroutineTest() {

        // 掛起函數(shù),要等代碼執(zhí)行完,才往下執(zhí)行
        val job = launch(Dispatchers.IO, CoroutineStart.LAZY) {

            // GlobalScope 頂級作用域 其它作用域取消,對其沒有影響
            GlobalScope.launch {
                // ...
                delay(1000)
            }

            val deferred = async(Dispatchers.IO) {
                "async result"
            }
            // withContext 掛起方法要在 協(xié)程 或者 suspend方法 里面調(diào)用 
            val withContextRes = withContext(Dispatchers.Default) {
                // ... 
                "withContext result"
            }

            // await 掛起方法 要在 協(xié)程 或者 suspend方法 里面調(diào)用 
            val asyncRes = deferred.await() // 掛起 獲取結(jié)果
        }
        // CoroutineStart.LAZY 要調(diào)用 start 或者 await()方法后才執(zhí)行
        job.start()
        // 取消并等待執(zhí)行完成
        job.cancelAndJoin()
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容