Kotlin協(xié)程一些概念理解

協(xié)程的概念

協(xié)程就是 Kotlin 提供的一套線程封裝的 API砰左,使用協(xié)程可以讓多線程之間的通信更加簡(jiǎn)單箭券≡驶總之一句話(huà)井联,協(xié)程可以簡(jiǎn)化異步編程卜壕。

舉個(gè)例子:在IO線程發(fā)起網(wǎng)絡(luò)請(qǐng)求,在主線程更新UI烙常。

如果使用 Retrofit +回調(diào)的方式轴捎,代碼類(lèi)似下面這樣

private fun normalRequest() {
    apiService.getWxarticle().enqueue(object : retrofit2.Callback<WxArticleResponse> {
        override fun onFailure(call: Call<WxArticleResponse>, t: Throwable) {
            //請(qǐng)求失敗
        }

        override fun onResponse(call: Call<WxArticleResponse>, response: retrofit2.Response<WxArticleResponse>) {
            //請(qǐng)求成功鹤盒,更新UI
        }
    })
}

如果使用 Retrofit +協(xié)程的方式,代碼類(lèi)似下面這樣

private fun coroutineRequest2_6() {
    launch(Dispatchers.Main) {//在主線程啟動(dòng)協(xié)程
        val response = apiService.getWxarticle2()//在后臺(tái)線程發(fā)起網(wǎng)絡(luò)請(qǐng)求
        tvResult.text = sb.toString()//在主線程更新UI
    }
}

對(duì)比使用Retrofit+回調(diào)的方式侦副,使用協(xié)程代碼明顯更加簡(jiǎn)潔清晰侦锯。

關(guān)于使用協(xié)程請(qǐng)求網(wǎng)絡(luò)請(qǐng)參考 Kotlin協(xié)程請(qǐng)求網(wǎng)絡(luò)

協(xié)程的掛起

看一個(gè)例子

private fun invokeMethod() {
    //注釋1處秦驯,在主線程啟動(dòng)協(xié)程
    scope.launch(Dispatchers.Main) {
        Log.i(TAG, "getString: current thread " + Thread.currentThread().name)
        val result = getString()//注釋2處尺碰,調(diào)用掛起函數(shù)
        etText.setText(result)//注釋3處
    }
}

//掛起函數(shù)
private suspend fun getString(): String {
    //切換到IO線程
    return withContext(Dispatchers.IO) {
        Log.i(TAG, "getString: current thread " + Thread.currentThread().name)
        "empty string"
    }
}

輸出結(jié)果

getString: current thread main
getString: current thread DefaultDispatcher-worker-2

注釋1處,在主線程啟動(dòng)一個(gè)協(xié)程译隘,就是指花括號(hào)里的這段代碼亲桥,scope.launch(Dispatchers.Main) {...}

注釋2處固耘,當(dāng)協(xié)程運(yùn)行到掛起函數(shù)的時(shí)候题篷,這個(gè)協(xié)程會(huì)被掛起。什么意思呢厅目?

  1. 從掛起函數(shù)getString()的第一個(gè)掛起點(diǎn)開(kāi)始當(dāng)前線程(在這個(gè)例子中是主線程)不再運(yùn)行協(xié)程中的代碼了番枚。第一個(gè)掛起點(diǎn):可以暫時(shí)理解為withContext(Dispatchers.IO){...}花括號(hào)里面的代碼塊。

  2. 掛起函數(shù)執(zhí)行完畢以后璧瞬,協(xié)程從掛起點(diǎn)恢復(fù)户辫,重新切回到當(dāng)前線程(在這個(gè)例子中是主線程)繼續(xù)執(zhí)行協(xié)程中的代碼。

etText.setText(result)

協(xié)程的掛起是非阻塞的是什么意思呢嗤锉?

這個(gè)其實(shí)非常非常簡(jiǎn)單渔欢,沒(méi)有什么高深的東西∥脸溃看代碼奥额。

  1. 阻塞的例子。
//在主線程執(zhí)行
btnSuspend.setOnClickListener {
    tvText1.text = getStringSuspend()
    tvText2.text = "興百姓苦访诱,亡百姓苦"
}

/**
 * 模擬耗時(shí)操作垫挨,2秒后返回字符串
 */
private fun getStringSuspend(): String {
    //讓主線程睡兩秒鐘,其實(shí)就是阻塞了主線程
    Thread.sleep(2000)
    return "峰巒如聚触菜,波濤如怒九榔,山河表里潼關(guān)路,望西都意躊躇涡相,傷心秦漢經(jīng)行處哲泊,宮闕萬(wàn)間都做了土。"
}

在上面的例子中催蝗,tvText1獲取顯示字符串是一個(gè)耗時(shí)操作切威。注釋1處,tvText2顯示text肯定是在tvText1顯示之后丙号。也就是說(shuō)當(dāng)前線程:主線程 被阻塞了先朦。當(dāng)前線程被阻塞以后當(dāng)前線程的后面的代碼是無(wú)法執(zhí)行的缰冤,必須等待阻塞結(jié)束。

  1. 協(xié)程的非阻塞
//在主線程執(zhí)行
private var scope: CoroutineScope = CoroutineScope(Dispatchers.Main)
btnUnSuspend.setOnClickListener {
        scope.launch {
            tvText1.text = getStringUnSuspend()
        }
        //注釋1處注意:這個(gè)代碼一定要卸載協(xié)程的代碼之外
        tvText2.text = "興百姓苦喳魏,亡百姓苦"
}

/**
 * 模擬耗時(shí)操作棉浸,2秒后返回字符串。
 */
private suspend fun getStringUnSuspend(): String {
    delay(2000)
    return "峰巒如聚截酷,波濤如怒涮拗,山河表里潼關(guān)路乾戏,望西都意躊躇迂苛,傷心秦漢經(jīng)行處,宮闕萬(wàn)間都做了土鼓择。"
}

現(xiàn)在三幻,tvText2先顯示text,然后2秒后tvText1才顯示了文字呐能。這里主線程沒(méi)有沒(méi)阻塞念搬,協(xié)程的delay(2000),實(shí)際上是在后臺(tái)線程阻塞(延遲了)2秒摆出,阻塞的是后臺(tái)線程朗徊。

注釋1處注意:這個(gè)代碼一定要協(xié)程的代碼之外。如果也寫(xiě)在launch的大括號(hào)之內(nèi)了偎漫,那么tvText2也是在tvText1顯示文字之后再顯示爷恳。這也說(shuō)明了在協(xié)程內(nèi)部,代碼也是順序執(zhí)行的象踊,一個(gè)父協(xié)程會(huì)等待子協(xié)程執(zhí)行完畢之后再繼續(xù)往下執(zhí)行温亲。

scope.launch {
    tvText1.text = getStringUnSuspend()
    tvText2.text = "興百姓苦,亡百姓苦"
}

/**
 * 模擬耗時(shí)操作杯矩,2秒后返回字符串栈虚。正確的的非阻塞,不阻塞當(dāng)前線程史隆,阻塞后臺(tái)線程魂务。
 */
private suspend fun getStringUnSuspend(): String {
    delay(2000)
    return "峰巒如聚,波濤如怒泌射,山河表里潼關(guān)路粘姜,望西都意躊躇,傷心秦漢經(jīng)行處魄幕,宮闕萬(wàn)間都做了土相艇。"
}

結(jié)論:非阻塞式掛起,就是說(shuō)掛起函數(shù)切到指定的線程執(zhí)行去了纯陨,執(zhí)行完畢以后會(huì)再切回到當(dāng)前線程繼續(xù)執(zhí)行協(xié)程中的代碼坛芽。在掛起函數(shù)切到別的線程執(zhí)行的這段期間留储,當(dāng)前線程是可以繼續(xù)運(yùn)行其他代碼的。

關(guān)于協(xié)程的掛起記住一句話(huà)就行:掛起函數(shù)掛起協(xié)程時(shí)咙轩,不會(huì)阻塞協(xié)程所在的線程获讳。

參考鏈接:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末煞烫,一起剝皮案震驚了整個(gè)濱河市浑此,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌滞详,老刑警劉巖凛俱,帶你破解...
    沈念sama閱讀 221,576評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異料饥,居然都是意外死亡蒲犬,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)岸啡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)原叮,“玉大人,你說(shuō)我怎么就攤上這事凰狞∑茫” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,017評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵赡若,是天一觀的道長(zhǎng)达布。 經(jīng)常有香客問(wèn)我,道長(zhǎng)逾冬,這世上最難降的妖魔是什么黍聂? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,626評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮身腻,結(jié)果婚禮上产还,老公的妹妹穿的比我還像新娘。我一直安慰自己嘀趟,他們只是感情好脐区,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,625評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著她按,像睡著了一般牛隅。 火紅的嫁衣襯著肌膚如雪炕柔。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,255評(píng)論 1 308
  • 那天媒佣,我揣著相機(jī)與錄音匕累,去河邊找鬼。 笑死默伍,一個(gè)胖子當(dāng)著我的面吹牛欢嘿,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播也糊,決...
    沈念sama閱讀 40,825評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼炼蹦,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了显设?” 一聲冷哼從身側(cè)響起框弛,我...
    開(kāi)封第一講書(shū)人閱讀 39,729評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎捕捂,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體斗搞,經(jīng)...
    沈念sama閱讀 46,271評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡指攒,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,363評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了僻焚。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片允悦。...
    茶點(diǎn)故事閱讀 40,498評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖虑啤,靈堂內(nèi)的尸體忽然破棺而出隙弛,到底是詐尸還是另有隱情,我是刑警寧澤狞山,帶...
    沈念sama閱讀 36,183評(píng)論 5 350
  • 正文 年R本政府宣布全闷,位于F島的核電站,受9級(jí)特大地震影響萍启,放射性物質(zhì)發(fā)生泄漏总珠。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,867評(píng)論 3 333
  • 文/蒙蒙 一勘纯、第九天 我趴在偏房一處隱蔽的房頂上張望局服。 院中可真熱鬧,春花似錦驳遵、人聲如沸淫奔。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,338評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)唆迁。三九已至佳鳖,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間媒惕,已是汗流浹背系吩。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,458評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留妒蔚,地道東北人穿挨。 一個(gè)月前我還...
    沈念sama閱讀 48,906評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像肴盏,于是被迫代替她去往敵國(guó)和親科盛。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,507評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容