coroutines
kotlin的協(xié)程在kotlin1.3有了很大變化弥鹦。嚣艇。禽翼。
1. 協(xié)程的啟動(building)
啟動協(xié)程的主要兩個方法
fun launch(): Job
fun async(): Deferred
1.1 launch
public fun CoroutineScope.launch(
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> Unit
): Job {
}
launch() 方法接收三個參數(shù)捍壤,通常很少用到第二個參數(shù)续誉。
第一個參數(shù)是一個協(xié)程的上下文,
CoroutineContext
不僅可以用于在協(xié)程跳轉(zhuǎn)的時刻傳遞數(shù)據(jù)扛吞,同時最主要的功能呻惕,是用于表明協(xié)程運行與恢復時的上下文環(huán)境。具體參數(shù)如下表
CoroutineDispatcher | --- | 對應的老版kotlin |
---|---|---|
Default | It is backed by a shared pool of threads on JVM. By default, the maximal number of threads used by this dispatcher is equal to the number CPU cores, but is at least two. | CommonPool |
Main | A coroutine dispatcher that is confined to the Main thread operating with UI objects. | UI |
Unconfined | It executes initial continuation of the coroutine immediately in the current call-frame and lets the coroutine resume in whatever thread that is used by the corresponding suspending function, without mandating any specific threading policy. | Unconfined |
IO | The [CoroutineDispatcher] that is designed for offloading blocking IO tasks to a shared pool of threads. |
老版本的協(xié)程滥比,通常
Android
在用的時候都是傳一個UI
就表示在 UI 線程啟動協(xié)程亚脆,或者傳一個CommonPool
表示在異步啟動協(xié)程,還有一個是Unconfined
表示不指定守呜,在哪個線程調(diào)用就在哪個線程恢復型酥。
public fun launch(
context: CoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> Unit
): Job {
}
// CoroutineContext, 不僅可以用于在協(xié)程跳轉(zhuǎn)的時刻傳遞數(shù)據(jù),同時最主要的功能查乒,是用于表明協(xié)程運行與恢復時的上下文環(huán)境弥喉。
1.2 async()方法
async()
方法也是創(chuàng)建一個協(xié)程并啟動,甚至連方法的聲明都跟launch()
方法一模一樣玛迄。
不同的是由境,async()
方法的返回值,返回的是一個Deferred
對象蓖议。這個接口是Job
接口的子類虏杰。
因此上文介紹的所有方法,都可以用于Deferred
的對象勒虾。
Deferred
最大的用處在于他特有的一個方法await()
:
public suspend fun await(): T
await()
可以返回當前協(xié)程的執(zhí)行結(jié)果纺阔,也就是你可以這樣寫代碼:
fun main(){
runBlocking {
val deferred1 = async(Dispatchers.Default) {
println(Thread.currentThread())
"hello1"
}
async(Dispatchers.Default){
println(Thread.currentThread())
println("hello2")
println(deferred1.await())
}
}
}
你發(fā)現(xiàn)神奇的地方了嗎,我讓一個工作在主線程的協(xié)程修然,獲取到了一個異步協(xié)程的返回值笛钝。
這意味著,我們以后網(wǎng)絡請求愕宋、圖片加載玻靡、數(shù)據(jù)庫、文件操作什么的中贝,都可以丟到一個異步的協(xié)程中去囤捻,然后在同步代碼中直接取返回值,而不再需要去寫回調(diào)了邻寿。
這就是我們經(jīng)常使用的一個最大特性蝎土。
Question
如果采用 GlobalScope啟動協(xié)程會怎么樣视哑?
fun main(){
runBlocking {
val deferred1 = async(Dispatchers.Default) {
println(Thread.currentThread())
"hello1"
}
async(Dispatchers.Default){
println(Thread.currentThread())
println("hello2")
println(deferred1.await())
}
}
}
// 運行結(jié)果
Thread[DefaultDispatcher-worker-1,5,main]
Thread[DefaultDispatcher-worker-3,5,main]
hello2
hello1