這些是作業系統( Operation System )中的基礎概念,用這張圖可以簡單區分他們
Application
就是開發者開發出來的程式碼,這時還沒載入到 Memory
中Application
,將 Application
載入 Memory
中,就是 Process
,在 Linux command line 上輸入 htop
,就可以看到目前有哪些 Process
正在執行中,並且 Process
之間是不能直接溝通的(如果可以任意呼叫到其他應用程式裏面的內容,那也有點太可怕了)Process
是 Thread
的容器,一個 Process
中可以持有多個 Thread
,Thread
共享資源Coroutine
一次只會執行一個 Job ,會透過頻繁切換 Job 達到類似異步的效果,需要的資源比開新的 Thread
少以昨天的例子說,如果採用 Synchronous 來處理的話,那會長的像這樣
fun fetchPirateList(): String {
val response = pirateService.fetchPirateList()
return response.body().toString()
}
那麼在第 6 行因為要等待 Server 回傳,因此就會卡住 Main thread ,而其他的任務也沒辦法拿到用戶可能就會看到卡住很久的畫面,因此我們需要做到的是讓這類型的任務跑在其他的 Thread 上(例如 IO thread ),讓 Main thread 可以去處理其他的工作
而且 Andorid OS 有一個機制是如果有人佔用 Main Thread 太久, App 就會 Crash 掉,相信剛開始寫 App 並且對非同步不熟的朋友應該都遇過很多次這樣的問題(就是在說我啦...)
CoroutineScope(Dispatchers.Main).launch {
val pirateListString = fetchPirateList() // Suspending function 跑在 I/O thread
updatePirateTextView(pirateListString) // updatePirateTextView() 會跑在 Main Thread,做更新 UI
}
suspend fun fetchPirateList(): String = withContext(Dispatchers.IO) {
// 從 Server 取得資料並回傳 PirateList String
val response = pirateService.fetchPirateList()
return response.body().toString()
}
Suspend function
可以暫停協程的執行,這意味著它將等待直到 suspending function
恢復,接下來會一一講解
指的是 Coroutine 作用的範圍,所有的 Coroutine 都會執行在 CoroutineScope 中
CoroutineContext
範圍,可根據需要定義 Thread
、Parent job
或 Exception handler
CoroutineScope(Dispatchers.Main + job + exceptionHandler).launch {
...
}
Main scope
通常都是在處理 UI 更新的任務或是 UI Component ,會透過 SupervisorJob()
在主線程上執行public fun MainScope(): CoroutineScope =
ContextScope(SupervisorJob() + Dispatchers.Main)
GlobalScope
不局限於任何 Job ,協程會在整個 Application 生命週期內運行指的是 Coroutine 作用的情境,也就是 Main thread 或是 IO thread 等
Dispatchers.Main
等同於 Android 中的 Main thread
Dispatchers.Default
使用共享的 Backend threads pool
,Dispatchers.Default
默認使用的最大線程數等於 CPU
內核數
Dispatchers.IO
與 Dispatchers.Default
共享線程,但是線程數受 kotlinx.coroutines.io.parallelism
限制,默認為 64 個線程或內核數(以較大者為準)
Dispatchers.Unconfined
不局限於任何特定線程的協程調度程序,默認在當前線程中執行
launch
在不阻塞當前線程的情況下啟動新的協程
async and awaitAsync
是 CoroutineScope
的擴展,並且通常會與 Await
做搭配,透過 Await
會等待 Async
執行完之後才會開始執行,
在CoroutineScope中運行的代碼( Regular function 或 Suspending functions ),將暫停協程直到完成
今天簡單的複習了 Coroutine
的部份,但其實也還沒完全了解,只能從字面上做解釋,還有很多更深入的部份還沒完全掌握好,今天寫的文章我覺得不是特別好,因此我會在之後了解更清楚,以及有更多使用上的心得後會在回頭更新這篇文章
明天可能會介紹 Flow
的部份, Flow
也是我近期才開始接觸的,昨天有提到他和 RxJava
常被拿來做比較,因此之後如果有機會碰到 RxJava
應該也會寫個文章來介紹喔