協(xié)程

什么是協(xié)程(Coroutine)

簡單來說散劫,協(xié)程像是輕量級的線程,但并不完全是線程。

首先侮繁,協(xié)程可以讓你順序地寫異步代碼虑粥,極大地降低了異步編程帶來的負(fù)擔(dān);

其次宪哩,協(xié)程更加高效娩贷。多個協(xié)程可以共用一個線程。一個 App 可以運行的線程數(shù)是有限的锁孟,但是可以運行的協(xié)程數(shù)量幾乎是無限的彬祖;

協(xié)程實現(xiàn)的基礎(chǔ)是可中斷的方法(suspending functions)∑烦椋可中斷的方法可以在任意的地方中斷協(xié)程的執(zhí)行储笑,直到該可中斷的方法返回結(jié)果或者執(zhí)行完成。

可中斷的方法(suspending functions) "suspend" 修飾方法

suspend fun suspendingFunction() : Int  {
    // Long running task
    return 0
}

協(xié)程上下文(Coroutine Context)

//運行在UI 線程 圆恤, 這種寫法會造成UI阻塞
CoroutineScope(Dispatchers.Main).launch() {
            val datas = RetrofitClient.create(GetDataAPI::class.java).getDatas()
}
//將網(wǎng)絡(luò)請求突倍,文件讀寫等其他方法放在IO線程中
withContext(Dispatchers.IO) {
             val datas = RetrofitClient.create(GetDataAPI::class.java).getDatas()
}
//最終寫法
CoroutineScope(Dispatchers.Main).launch() {
            withContext(Dispatchers.IO) {
                   val datas = RetrofitClient.create(GetDataAPI::class.java).getDatas()
            }
}

目前為止,我們認(rèn)識了兩個 dispatcher盆昙,下面我們詳細(xì)介紹一下所有的 dispatcher 的使用場景羽历。

Default

當(dāng)我們未指定 dispatcher 的時候會默認(rèn)使用,當(dāng)然淡喜,我們也可以明確設(shè)置使用它秕磷。它一般用于 CPU 密集型的任務(wù),特別是涉及到計算、算法的場景炼团。它可以使用和 CPU 核數(shù)一樣多的線程跳夭。正因為是密集型的任務(wù),同時運行多個線程并沒有意義们镜,因為 CPU 將會很繁忙币叹。

IO

它用于輸入/輸出的場景。通常模狭,涉及到會阻塞線程颈抚,需要等待另一個系統(tǒng)響應(yīng)的任務(wù),比如:網(wǎng)絡(luò)請求嚼鹉、數(shù)據(jù)庫操作贩汉、文件讀寫等,都可以使用它锚赤。因為它不使用 CPU 匹舞,可以同一時間運行多個線程,默認(rèn)是數(shù)量為 64 的線程池线脚。Android App 中有很多網(wǎng)絡(luò)請求的操作赐稽,所以你可能會經(jīng)常用到它叫榕。

UnConfined

如果你不在乎啟動了多少個線程,那么你可以使用它姊舵。它使用的線程是不可控制的晰绎,除非你特別清楚你在做什么,否則不建議使用它括丁。

Main

這是 UI 相關(guān)的協(xié)程庫里面的一個 dispatcher荞下,在 Android 編程中,它使用的是 UI 線程史飞。

協(xié)程構(gòu)造器(Coroutine Builders)

runBlocking

這個協(xié)程構(gòu)造器會阻塞當(dāng)前線程尖昏,直到協(xié)程內(nèi)的所有任務(wù)執(zhí)行完畢。

launch

這個協(xié)程構(gòu)造器很重要构资,因為它可以很輕易地創(chuàng)建一個協(xié)程会宪,你可能會經(jīng)常用到它。和 runBlocking 相反的是蚯窥,它不會阻塞當(dāng)前線程(前提是我們使用了合適的 dispatcher)。
launch 方法會返回一個 Job塞帐,Job 繼承了協(xié)程上下文(CoroutineContext)拦赠。

job.join

將當(dāng)前協(xié)程阻塞執(zhí)行王當(dāng)前異步在按照順序執(zhí)行下一個異步。

job.cancel

這個方法可以取消所有與其關(guān)聯(lián)的子 Job葵姥。也就是相當(dāng)于取消當(dāng)前異步荷鼠。
job.cancel() 是一個普通方法,所以它不必運行在協(xié)程內(nèi)部榔幸。

async

async 允許并行地運行多個子線程任務(wù)允乐,它不是一個可中斷方法,所以當(dāng)調(diào)用 async 啟動子協(xié)程的同時削咆,后面的代碼也會立即執(zhí)行牍疏。async 通常需要運行在另外一個協(xié)程內(nèi)部,它會返回一個特殊的 Job拨齐,叫作 Deferred鳞陨。
Deferred 有一個新的方法叫做 await(),它是一個可中斷的方法瞻惋,當(dāng)我們需要獲取 async 的結(jié)果時厦滤,需要調(diào)用 await() 方法等待結(jié)果。調(diào)用 await() 方法后歼狼,會中斷當(dāng)前協(xié)程掏导,直到其返回結(jié)果。

作用域(Scope)

Global scope

它是一個全局的作用域羽峰,如果協(xié)程的運行周期和 App 的生命周期一樣長的話趟咆,創(chuàng)建協(xié)程的時候可以使用它添瓷。所以它不應(yīng)該和任何可以被銷毀的組件綁定使用。

viewModelScope

這是一個跟ViewModel綁定的作用域忍啸,ViewModel跟Activity/Fragment生命周期綁定仰坦,所以viewModelScope的作用域跟Activity/Fragment生命周期一樣。

回調(diào)方式轉(zhuǎn)為協(xié)程

如果你已經(jīng)考慮將協(xié)程用于現(xiàn)有的項目计雌,你可能會考慮怎么將現(xiàn)有的回調(diào)風(fēng)格的代碼轉(zhuǎn)為協(xié)程:

suspend fun suspendAsyncLogin(username: String, password: String): User =
    suspendCancellableCoroutine { continuation ->
        userService.doLoginAsync(username, password) { user ->
            continuation.resume(user)
}

suspendCancellableCoroutine() 這個方法返回一個 continuation 對象悄晃,continuation 可以用于返回回調(diào)的結(jié)果。只要調(diào)用 continuation.resume() 方法凿滤,這個回調(diào)結(jié)果就可以作為這個可中斷方法的結(jié)果返回給協(xié)程妈橄。

轉(zhuǎn)載自

https://blog.csdn.net/weixin_33701617/article/details/91375647

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市翁脆,隨后出現(xiàn)的幾起案子眷蚓,更是在濱河造成了極大的恐慌,老刑警劉巖反番,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件沙热,死亡現(xiàn)場離奇詭異,居然都是意外死亡罢缸,警方通過查閱死者的電腦和手機(jī)篙贸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來枫疆,“玉大人爵川,你說我怎么就攤上這事∠⑿ǎ” “怎么了寝贡?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長值依。 經(jīng)常有香客問我圃泡,道長,這世上最難降的妖魔是什么愿险? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任洞焙,我火速辦了婚禮,結(jié)果婚禮上拯啦,老公的妹妹穿的比我還像新娘澡匪。我一直安慰自己,他們只是感情好褒链,可當(dāng)我...
    茶點故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布唁情。 她就那樣靜靜地躺著,像睡著了一般甫匹。 火紅的嫁衣襯著肌膚如雪甸鸟。 梳的紋絲不亂的頭發(fā)上惦费,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天,我揣著相機(jī)與錄音抢韭,去河邊找鬼薪贫。 笑死,一個胖子當(dāng)著我的面吹牛刻恭,可吹牛的內(nèi)容都是我干的瞧省。 我是一名探鬼主播,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼鳍贾,長吁一口氣:“原來是場噩夢啊……” “哼鞍匾!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起骑科,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤橡淑,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后咆爽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體梁棠,經(jīng)...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年斗埂,在試婚紗的時候發(fā)現(xiàn)自己被綠了符糊。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,711評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡蜜笤,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出盐碱,到底是詐尸還是另有隱情把兔,我是刑警寧澤,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布瓮顽,位于F島的核電站县好,受9級特大地震影響拄衰,放射性物質(zhì)發(fā)生泄漏阿宅。R本人自食惡果不足惜踱蠢,卻給世界環(huán)境...
    茶點故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一低缩、第九天 我趴在偏房一處隱蔽的房頂上張望点寥。 院中可真熱鬧荡短,春花似錦碟嘴、人聲如沸鞋既。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至泪勒,卻和暖如春昼蛀,著一層夾襖步出監(jiān)牢的瞬間宴猾,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工叼旋, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留仇哆,地道東北人。 一個月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓夫植,卻偏偏與公主長得像讹剔,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子偷崩,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,611評論 2 353

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