iT邦幫忙

2021 iThome 鐵人賽

DAY 16
0

前言

今天東西不多,算是給前面做一個補充資訊,明天開始會講Flow了,又是會是超長的文章

正文

想不到吧? job也有生命週期,我沒有亂套名詞喔,文檔自己寫life-cycle的,相信大家已經對job和coroutine的父子層級結構十分清楚了吧!
不清楚的看繼承這篇取消這篇

之前我們講過job在呼叫cancel後,並不會直接取消,而是先進入canceling的狀態,今天就是要講講job的那些狀態

狀態和生命週期

job的state有多重要,你先把她想像成fragment,你要在裡面執行的程式都須確保fragment還活著,你說,重不重要

那job的state有哪些,分別是創建時(New)、運行中(Active)、準備完成(Completing)、完成(Completed)、取消中(Cancelling)和已取消(Cancelled六種)


source: https://medium.com/androiddevelopers/coroutines-first-things-first-e6187bf3bb21

這兩張圖一樣,自己挑容易理解的那張看即可,job的state比起activity或fragment簡單許多,只有6個狀態,扣掉開始、結束、取消,剩下三種,基本上你已經學會了,然而對job的state我們並不能夠直接訪問狀態,我們必須透過isActive, isCancelled 和isCompleted的方法,回傳的boolean去檢查

在邊再次提醒,除了job.cancel(),當coroutine throw Exception時,也會進入canceling 狀態

cancel的描述很簡單,cancel()呼叫後會到canceled,但明明cancelled沒有箭頭到completed,這兩個isCancel和isComplete卻可能同時回傳true,這是因為一個以取消的job也可以被視為完成; 另一方面,一個正常完成的job,她會知道自己不是被呼叫cancel()或是fail而取消的,所以正常完成的job,isCancel會是false

try {
    thirdJob.complete()
} catch (e:Exception){
    Timber.e(e)
}finally {
    Timber.d(thirdJob.isActive.toString())
    Timber.d(thirdJob.isCancelled.toString())
    Timber.d(thirdJob.isCompleted.toString())
    thirdJob.cancel()
}
delay(1000)
Timber.d(thirdJob.isActive.toString())
Timber.d(thirdJob.isCancelled.toString())
Timber.d(thirdJob.isCompleted.toString())

刺激的來了,每次印出來的結果不一定相同

D/CoroutineFragment$test: true //isActive
D/CoroutineFragment$test: false //isCancelled
D/CoroutineFragment$test: false //isCompleted
D/CoroutineFragment$test: finally-----------------------
D/CoroutineFragment$test: false //isActive
D/CoroutineFragment$test: true //isCancelled
D/CoroutineFragment$test: true //isCompleted
D/CoroutineFragment$test: outside-----------------------

cancel和complete位子互換

D/CoroutineFragment$test: false //isActive
D/CoroutineFragment$test: true //isCancelled
D/CoroutineFragment$test: false //isCompleted
D/CoroutineFragment$test: finally-----------------------
D/CoroutineFragment$test: false //isActive
D/CoroutineFragment$test: true //isCancelled
D/CoroutineFragment$test: true //isCompleted
D/CoroutineFragment$test: outside-----------------------

If we just call cancel, it doesn’t mean that the coroutine work will just stop. If you’re performing some relatively heavy computation, like reading from multiple files, there’s nothing that automatically stops your code from running.
而會造成這樣的原因是當我們呼叫了cancel 或Complete時,他並不是立刻切換狀態,而是會等到工作結束,這部分我在之前的cancel有講過了,但我們依然能得到的結論,isCancelled和isCompleted的狀態可以同時存在

表格,可以看到個狀態對應的回傳值

連結

coroutine first thing first
官方blog


上一篇
day15 job的騷操作
下一篇
day17 不懂kotlin flow資料流? 那喝杯進口奶茶吧
系列文
解鎖kotlin coroutine的各種姿勢-新手篇30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言