withContext 切換執行緒
執行緒
- Dispatchers.IO
- Dispatchers.Default
- Dispatchers.Main
協程作用域
因為withContext是suspend 函式,所以要在協程作用域中,才能使用withContext()函式。
Junit的coroutine scope(協程作用域)是runBlocking,只有在runBlocking協程作用域下,就能呼叫suspend()函式。
1
2
3
4
5
6
7
8
@Test
fun coroutine13() = runBlocking {
// 切換至IO執行緒
withContext(Dispatchers.IO) {
// 程式碼
}
println(result2)
}
使用方式1
withContext是suspend函式,要放在suspend函式中。
1
2
3
4
5
6
7
8
9
10
11
suspend fun funName() {
withContext(Dispatchers.IO) {
delay(1000)
println("test")
}
}
@Test
fun coroutine14() = runBlocking {
funName()
}
使用方式2
函式傳回值是withContext
1
2
3
4
5
6
7
8
9
suspend fun funName() = withContext(Dispatchers.IO) {
delay(1000)
println("test")
}
@Test
fun coroutine14() = runBlocking {
funName()
}
使用方式3
函式傳回值是協程作用域coroutineScope
1
2
3
4
5
6
7
8
9
10
11
suspend fun funName() = coroutineScope {
withContext(Dispatchers.IO) {
delay(1000)
println("test")
}
}
@Test
fun coroutine14() = runBlocking {
funName()
}
使用方式4
包在協程作用域中(coroutineScope、CoroutineScope、GlobalScope)。
1
2
3
4
5
6
7
8
9
@Test
fun coroutine14() = runBlocking {
coroutineScope {
withContext(Dispatchers.IO) {
delay(1000)
println("test")
}
}
}
使用方式5
包在協程中(launch、async)。
1
2
3
4
5
6
7
8
9
10
@Test
fun coroutine14() = runBlocking {
launch {
withContext(Dispatchers.IO) {
delay(1000)
println("test")
}
}
println()
}
使用方式6
在Activity,不能在Test Case。
1
2
3
4
5
6
7
8
9
GlobalScope.launch (Dispatchers.Main) {
// 切換至io
withContext (Dispatchers.IO) {
delay(1000)
println("io")
}
// 切換回 main
println("main")
}
順序執行
即便result2的delay秒數才500,但也是先執行完result1,才執行result2。
1
2
3
4
5
6
7
8
9
10
11
12
13
@Test
fun coroutine13() = runBlocking<Unit> {
val result1 = withContext(Dispatchers.IO) {
delay(1000)
"result1"
}
println(result1)
val result2 = withContext(Dispatchers.IO) {
delay(500)
"result2"
}
println(result2)
}
result1
result2
非同步執行
非同步,我自己的記法是多個協程同時執行,不用等待其它協程執行完畢。
使用launch包住withContext,就可以變成非同步。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Test
fun coroutine15() = runBlocking {
launch {
val result1 = withContext(Dispatchers.IO) {
delay(1000)
"result1"
}
println(result1)
}
launch {
val result2 = withContext(Dispatchers.IO) {
delay(500)
"result2"
}
println(result2)
}
println()
}
result2
result1