CoroutineContext

CoroutineContext,協程上下文,由以下四個元素所組成。

元素類型 作用 範例
Job 管理協程生命週期 Job()
Dispatcher 決定執行緒 Dispatchers.IO、Dispatchers.Main
CoroutineName 協程名稱(除錯用) CoroutineName(“MyCoroutine”)
CoroutineExceptionHandler 異常處理 CoroutineExceptionHandler

輸出上下文

使用時記得要加上大括號。

1
${coroutineContext[Job]}

完整程式碼

1
2
3
4
5
6
7
8
fun coroutin07() = runBlocking {
  println("job = ${coroutineContext[Job]}")
  println("dispatcher = ${coroutineContext[CoroutineDispatcher]}")
  println("name = ${coroutineContext[CoroutineName]}")
  // 獲取特定元素
  val job = coroutineContext.job
  println("協程Job: $job")
}
job = "coroutine#1":BlockingCoroutine{Active}@25bfcafd
dispatcher = BlockingEventLoop@6fe1b4fb
name = null
協程Job: "coroutine#1":BlockingCoroutine{Active}@25bfcafd

coroutine#1 為 job 的名字。

調度器Dispatchers

Dispatchers調度器決定協程是在那個Thread運行。
預設是目前runBlocking{}的Thread。

Android的Main Thread是處理UI。

Dispatchers分類如下:

  • Dispatchers.Main 畫面UI
  • Dispatchers.IO 網路傳輸、資料庫、File存取
  • Dispatchers.Default Cpu運算
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  @Test
  fun coroutin08() = runBlocking {
    launch {
      println("main Thread = ${Thread.currentThread().name}")
    }

    launch(Dispatchers.IO){
      println("IO Thread = ${Thread.currentThread().name}")
    }

    launch(Dispatchers.Default){
      println("Default Thread = ${Thread.currentThread().name}")
    }

    launch (newSingleThreadContext("MyThread")) {
      println("Custom Thread = ${Thread.currentThread().name}")
    }
    println("test")
  }

最後面加上println("test"),是因為出現了以下錯誤訊息。

Method 'coroutin07' annotated with '@Test' should be of type 'void'

runBlocking{},要有任何程式碼,而不能只是launch() {}

執行結果:

IO Thread = DefaultDispatcher-worker-1 @coroutine#3
Default Thread = DefaultDispatcher-worker-3 @coroutine#4
Custom Thread = MyThread @coroutine#5
test
main Thread = Test worker @coroutine#2

由執行結果可以發現,Thread Name都不同。
IO跟Default,是以DefaultDispatcher-worker-為開頭,後面是 @協程編號

協程編號是根據建立的次序。如:第一個被建立的 coroutine,就會是@coroutine#1

自訂CoroutineContext

  • Job() 自己建立一個job物件
  • Dispatchers.IO 調度器是IO
  • CoroutineName名字是test

輸出CoroutineContext與Thread name

1
2
3
4
5
6
7
8
9
fun coroutine09() = runBlocking {
  val scope = CoroutineScope(Job() + Dispatchers.IO
      + CoroutineName("test"))
  val job1 = scope.launch {
    println("${coroutineContext[Job]}")
    println("${Thread.currentThread().name}")
  }
  job1.join()
}
"test#3":StandaloneCoroutine{Active}@5a5ff9a1
DefaultDispatcher-worker-1 @test#3

CoroutineName名字

名字#編號
test#3

物件名

@5a5ff9a1

results matching ""

    No results matching ""