Kotlin協(xié)程的啟動方式介紹
啟動協(xié)程的基本方式
1.GlobalScope.launch
代碼示例:
fun testGlobalScope() { GlobalScope.launch { println("Coroutinue started!") delay(1000L) println("Hello World!") } println("After launch!") Thread.sleep(2000L) println("Process end!") } /** * After launch! * Coroutinue started! * Hello World! * Process end! */
@DelicateCoroutinesApi public object GlobalScope : CoroutineScope { /** * Returns [EmptyCoroutineContext]. */ override val coroutineContext: CoroutineContext get() = EmptyCoroutineContext }
public fun CoroutineScope.launch( context: CoroutineContext = EmptyCoroutineContext, start: CoroutineStart = CoroutineStart.DEFAULT, block: suspend CoroutineScope.() -> Unit ): Job { val newContext = newCoroutineContext(context) val coroutine = if (start.isLazy) LazyStandaloneCoroutine(newContext, block) else StandaloneCoroutine(newContext, active = true) coroutine.start(start, coroutine, block) return coroutine }
launch函數(shù)是CoroutineScope的擴展函數(shù),它有三個參數(shù):
- context: CoroutineContext = EmptyCoroutineContext, 第一個參數(shù)是協(xié)程上下文,它的默認(rèn)值是 EmptyCoroutineContext,如果不傳這個參數(shù),默認(rèn)就會使用 EmptyCoroutineContext。也可以傳入 Kotlin 官方為我們提供的 Dispatchers,來指定協(xié)程運行的線程池。(Dispatchers.IO、Dispatchers.Unconfined、Dispatchers.Main)
- start: CoroutineStart = CoroutineStart.DEFAULT,第二個參數(shù)是協(xié)程的啟動模式,默認(rèn)值是CoroutineStart.DEFAULT,CoroutineStart 是一個枚舉類,一共有:DEFAULT、LAZY、ATOMIC、UNDISPATCHED。
- block: suspend CoroutineScope.() -> Unit,第三個參數(shù)是函數(shù)類型block,它的類型是suspend CoroutineScope.() -> Unit。本質(zhì)是一個掛起函數(shù)。
- 函數(shù)的返回值是一個 Job,它其實代表的是協(xié)程的句柄,并不能返回協(xié)程的執(zhí)行結(jié)果。
2.runBlocking 啟動協(xié)程
代碼示例
fun testRunBlocking2() { runBlocking { println("Coroutinue started!") delay(1000L) println("Hello World!") } println("After Launch") Thread.sleep(2000L) println("Process end") } /** * Coroutinue started! * Hello World! * After Launch * Process end */
@Throws(InterruptedException::class) public actual fun <T> runBlocking(context: CoroutineContext, block: suspend CoroutineScope.() -> T): T { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } val currentThread = Thread.currentThread() val contextInterceptor = context[ContinuationInterceptor] val eventLoop: EventLoop? val newContext: CoroutineContext if (contextInterceptor == null) { // create or use private event loop if no dispatcher is specified eventLoop = ThreadLocalEventLoop.eventLoop newContext = GlobalScope.newCoroutineContext(context + eventLoop) } else { // See if context's interceptor is an event loop that we shall use (to support TestContext) // or take an existing thread-local event loop if present to avoid blocking it (but don't create one) eventLoop = (contextInterceptor as? EventLoop)?.takeIf { it.shouldBeProcessedFromContext() } ?: ThreadLocalEventLoop.currentOrNull() newContext = GlobalScope.newCoroutineContext(context) } val coroutine = BlockingCoroutine<T>(newContext, currentThread, eventLoop) coroutine.start(CoroutineStart.DEFAULT, coroutine, block) return coroutine.joinBlocking() }
runBlocking是普通函數(shù),第一個參數(shù):context: CoroutineContext,協(xié)程上下文。第二個參數(shù)是函數(shù)類型,block: suspend CoroutineScope.() -> T,函數(shù)類型是有返回值類型 T 的,與 runBlocking 的返回值類型是一樣的,runBlocking 其實是可以從協(xié)程當(dāng)中返回執(zhí)行結(jié)果的。
fun testRunBlocking() { val runBlockingResult = runBlocking { delay(500L) return@runBlocking "HaHa" } println("result:$runBlockingResult") } result:HaHa
runBlocking特點:
runBlocking 啟動的協(xié)程會阻塞當(dāng)前線程的執(zhí)行。
3.async啟動協(xié)程
使用 async{} 創(chuàng)建協(xié)程,可以通過它返回的Deferred拿到協(xié)程的執(zhí)行結(jié)果。
代碼示例
fun testAsync() { runBlocking { val deferred = async { println("do async:${Thread.currentThread().name}") delay(1000L) return@async "do completed" } println("After async:${Thread.currentThread().name}") val result = deferred.await() println("Result is: $result") } } After async:main @coroutine#1 do async:main @coroutine#2 Result is: do completed
public fun <T> CoroutineScope.async( context: CoroutineContext = EmptyCoroutineContext, start: CoroutineStart = CoroutineStart.DEFAULT, block: suspend CoroutineScope.() -> T ): Deferred<T> { val newContext = newCoroutineContext(context) val coroutine = if (start.isLazy) LazyDeferredCoroutine(newContext, block) else DeferredCoroutine<T>(newContext, active = true) coroutine.start(start, coroutine, block) return coroutine }
async注意點
- async 啟動協(xié)程以后,不會阻塞當(dāng)前程序的執(zhí)行流程。
- async{}的返回值,是一個 Deferred 對象,它的 await() 方法,就可以拿到協(xié)程的執(zhí)行結(jié)果。
- await只是等待執(zhí)行完,并不是觸發(fā)執(zhí)行。
到此這篇關(guān)于Kotlin協(xié)程的啟動方式介紹的文章就介紹到這了,更多相關(guān)Kotlin協(xié)程啟動內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android System fastboot 介紹和使用教程
Fastboot是Android快速升級的一種方法,Fastboot的協(xié)議fastboot_protocol.txt在源碼目錄./bootable/bootloader/legacy下可以找到,本文給大家介紹Android System fastboot 介紹和使用教程,感興趣的朋友一起看看吧2024-01-01Android創(chuàng)建外部lib庫及自定義View的圖文教程
這篇文章主要給大家介紹了關(guān)于Android創(chuàng)建外部lib庫及自定義View的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-11-11詳解android使用ItemDecoration 懸浮導(dǎo)航欄效果
本篇文章主要介紹了Android 最流行的吸頂效果的實現(xiàn)及代碼,非常具有實用價值,需要的朋友可以參考下。2017-01-01Android實現(xiàn)圖片自動切換功能(實例代碼詳解)
這篇文章主要介紹了Android實現(xiàn)圖片自動切換功能,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2020-02-02Android 實現(xiàn)夜間模式的快速簡單方法實例詳解
這篇文章主要介紹了Android 實現(xiàn)夜間模式的快速簡單方法,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2016-09-09Android中監(jiān)聽軟鍵盤顯示狀態(tài)實現(xiàn)代碼
這篇文章主要介紹了Android中監(jiān)聽軟鍵盤顯示狀態(tài)實現(xiàn)代碼,本文直接給出核心實現(xiàn)代碼,需要的朋友可以參考下2015-04-04