這些是作業系統( 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 應該也會寫個文章來介紹喔