Android kotlin協程

說明

  • 可代替線程整異步
  • 可控制,靈活 (控制優先級,內存占用等)
  • 速度快 效率高
  • 有數量上限

使用

  • runBlocking 一般用于測試 不建議使用
  • GlobalScope.launch 全局的 生命周期跟隨application 不建議使用
  • CoroutineScope(job) 用
    基本使用
  runBlocking {Log.i("test_coroutine","我是一個runBlocking")}Log.i("test_coroutine","我在 runBlocking 協程外 且在 協程后")GlobalScope.launch {Log.i("test_coroutine","我是一個GlobalScope")}Log.i("test_coroutine","我在 GlobalScope 協程外 且在 協程后")val job = Job()val coroutineScope = CoroutineScope(job)coroutineScope.launch {Log.i("test_coroutine","我是一個coroutineScope")}Log.i("test_coroutine","我在 coroutineScope 協程外 且在 協程后")

結果
在這里插入圖片描述
分析

runBlocking 阻塞主線程 執行了協程后 繼續執行

GlobalScope.launch 不阻塞 繼續執行主線程 后執行協程
coroutineScope.launch 不阻塞 繼續執行主線程 后執行協程

  • 增加延時,效果更明顯 delay(1000)
  runBlocking {delay(1000)Log.i("test_coroutine","我是一個runBlocking")}Log.i("test_coroutine","我在 runBlocking 協程外 且在 協程后")GlobalScope.launch {delay(1000)Log.i("test_coroutine","我是一個GlobalScope")}Log.i("test_coroutine","我在 GlobalScope 協程外 且在 協程后")val job = Job()val coroutineScope = CoroutineScope(job)coroutineScope.launch {delay(1000)Log.i("test_coroutine","我是一個coroutineScope")}Log.i("test_coroutine","我在 coroutineScope 協程外 且在 協程后")

結果
在這里插入圖片描述
分析

runBlocking 阻塞主線程 執行了協程后 繼續執行

GlobalScope.launch 協程內容最后執行
coroutineScope.launch 協程內容最后執行

1.1 協程里的掛起

 val coroutineScope = CoroutineScope(Job())val job = coroutineScope.launch {delay(1000)Log.i("test_coroutine","我是一個coroutineScope")      //1launch {delay(1000)Log.i("test_coroutine","我是一個coroutineScope 里的 launch")  // 4delay(1000)Log.i("test_coroutine","我是一個coroutineScope 里的 launch1")  //5}Log.i("test_coroutine","我是一個coroutineScope1")  // 2Log.i("test_coroutine","我是一個coroutineScope2")  // 3}

結果
在這里插入圖片描述
繼續玩

 val coroutineScope = CoroutineScope(Job())val job = coroutineScope.launch {delay(1000)Log.i("test_coroutine","我是一個coroutineScope")   //1launch {delay(1000)Log.i("test_coroutine","我是一個coroutineScope 里的 launch")  //3delay(1000)Log.i("test_coroutine","我是一個coroutineScope 里的 launch1")  //5}Log.i("test_coroutine","我是一個coroutineScope1")  //2delay(1500)                                          //多了個delayLog.i("test_coroutine","我是一個coroutineScope2")  //4}

結果
在這里插入圖片描述

  • join()
 val coroutineScope = CoroutineScope(Job())val job = coroutineScope.launch {delay(1000)Log.i("test_coroutine","我是一個coroutineScope")  //1val job1 = launch {delay(1000)Log.i("test_coroutine","我是一個coroutineScope 里的 launch")  //3delay(1000)Log.i("test_coroutine","我是一個coroutineScope 里的 launch1")  //4}Log.i("test_coroutine","我是一個coroutineScope1")  //2job1.join()delay(1500)                                          //多了個delayLog.i("test_coroutine","我是一個coroutineScope2")  //5}

結果: 執行的時候 job1加入了進來
在這里插入圖片描述

  • cancel()
 val coroutineScope = CoroutineScope(Job())val job = coroutineScope.launch {delay(1000)Log.i("test_coroutine","我是一個coroutineScope")  //1val job1 = launch {delay(1000)Log.i("test_coroutine","我是一個coroutineScope 里的 launch")  //3delay(1000)Log.i("test_coroutine","我是一個coroutineScope 里的 launch1")  //不執行}Log.i("test_coroutine","我是一個coroutineScope1")  //2delay(1500)                                          //多了個delayLog.i("test_coroutine","我是一個coroutineScope2")  //4cancel()}

結果 job 和 子job1都停了
在這里插入圖片描述

  • job1.cancel()
 val coroutineScope = CoroutineScope(Job())val job = coroutineScope.launch {delay(1000)Log.i("test_coroutine","我是一個coroutineScope")val job1 = launch {delay(1000)Log.i("test_coroutine","我是一個coroutineScope 里的 launch")delay(1000)Log.i("test_coroutine","我是一個coroutineScope 里的 launch1")}Log.i("test_coroutine","我是一個coroutineScope1")delay(1500)                                          //多了個delayLog.i("test_coroutine","我是一個coroutineScope2")job1.cancel()Log.i("test_coroutine","我是一個coroutineScope3")}

結果 job繼續執行 job1停了
在這里插入圖片描述

  • job1.cancelAndJoin() 執行完之后 取消
  val coroutineScope = CoroutineScope(Job())val job = coroutineScope.launch {delay(1000)Log.i("test_coroutine","我是一個coroutineScope")val job1 = launch {var i = 0while(i<10){yield()delay(500)Log.i("test_coroutine","我是一個coroutineScope 里的 launch>>${i++}")}}Log.i("test_coroutine","我是一個coroutineScope1")delay(1500)                                          //多了個delayLog.i("test_coroutine","我是一個coroutineScope2")job1.join()job1.cancel()Log.i("test_coroutine","我是一個coroutineScope3")}

結果 job1并沒有被取消
在這里插入圖片描述

  • job1.cancelAndJoin()
   val coroutineScope = CoroutineScope(Job())val job = coroutineScope.launch {delay(1000)Log.i("test_coroutine","我是一個coroutineScope")val job1 = launch {var i = 0while(i<10){yield()delay(500)Log.i("test_coroutine","我是一個coroutineScope 里的 launch>>${i++}")}}Log.i("test_coroutine","我是一個coroutineScope1")delay(1500)                                          //多了個delayLog.i("test_coroutine","我是一個coroutineScope2")job1.cancelAndJoin()Log.i("test_coroutine","我是一個coroutineScope3")}

結果
在這里插入圖片描述

  • ensureActive() 在協程不在 active 狀態時會立即拋出異常。

  • yield() yield 會進行的第一個工作就是檢查任務是否完成,如果 Job 已經完成的話,就會拋出 CancellationException 來結束協程。yield 應該在定時檢查中最先被調用

  • async

 val async = async {var i = 0while(i<10 && isActive){delay(500)Log.i("test_coroutine","我是一個coroutineScope 里的 launch>>${i++}")}"完事啦"}Log.i("test_coroutine","我是一個coroutineScope1")delay(1500)                                          //多了個delayLog.i("test_coroutine","我是一個coroutineScope2")val result = async.await()Log.i("test_coroutine","我是一個coroutineScope3 result>"+result)Log.i("test_coroutine","我是一個coroutineScope4")

結果
在這里插入圖片描述

  • withTimeout
 Log.i("test_coroutine","我是一個coroutineScope")withTimeout(3000){var i = 0while(i<10 && isActive){delay(500)Log.i("test_coroutine","我是一個coroutineScope 里的 launch>>${i++}")}}Log.i("test_coroutine","我是一個coroutineScope1")delay(1500)                                          //多了個delayLog.i("test_coroutine","我是一個coroutineScope2")

結果 時間到后所在的協程也不繼續執行了
在這里插入圖片描述

Android中的協程

  • MainScope
MainScope().launch {}
  • viewModelScope
    implementation ‘androidx.lifecycle:lifecycle-viewmodel-android:2.8.0’
    implementation ‘androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.0’
    implementation ‘androidx.lifecycle:lifecycle-common:2.8.0’
 viewModelScope.launch {}
  • lifecycleScope
  lifecycleScope.launch {}

在這里插入圖片描述

  • rememberCoroutineScope() 可能會因為組件狀態變化而移除此協程
@Composable
inline fun rememberCoroutineScope(crossinline getContext: @DisallowComposableCalls () -> CoroutineContext ={ EmptyCoroutineContext }
): CoroutineScope {val composer = currentComposerval wrapper = remember {CompositionScopedCoroutineScopeCanceller(createCompositionCoroutineScope(getContext(), composer))}return wrapper.coroutineScope
}
  • currentRecomposeScope currentRecomposeScope 是一個在任何Composable函數中都能訪問的成員
    作用是使當前時刻組合無效,強制觸發重組
val currentRecomposeScope: RecomposeScope@ReadOnlyComposable@OptIn(InternalComposeApi::class)@Composable get() {val scope = currentComposer.recomposeScope ?: error("no recompose scope found")currentComposer.recordUsed(scope)return scope}
  • supervisorScope 協程異常不影響其他協程
  • coroutineScope 有異常所有攜程都退出

本文參考 https://blog.csdn.net/Code1994/article/details/129448142

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/15474.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/15474.shtml
英文地址,請注明出處:http://en.pswp.cn/web/15474.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

櫻花下落的速度是每秒5厘米,我們的心又該以什么速度去接近呢

櫻花下落的速度是每秒五厘米。5年前第一次接觸秒速五厘米的時候&#xff0c;我還在念初中&#xff0c;那時候的我尚且理解不了作品里的太多東西&#xff0c;只是為那輛列車隔開了明里和貴樹感到悲傷&#xff0c;為他們二人那段無疾而終的感情感到遺憾。五年后再一次重溫&#x…

GEE批量導出逐日、逐月、逐季節和逐年的遙感影像(以NDVI為例)

影像導出 1.逐日數據導出2.逐月數據導出3.季節數據導出4.逐年數據導出 最近很多小伙伴們私信我&#xff0c;問我如何高效導出遙感數據&#xff0c;從逐日到逐季度&#xff0c;我都有一套自己的方法&#xff0c;今天就來和大家分享一下&#xff01; ??&#x1f50d;【逐日導出…

Scala 入門介紹和環境搭建

一、簡介 Scala 是一門以 Java 虛擬機&#xff08;JVM&#xff09;為運行環境并將面向對象和函數式編程的最佳特性結合在一起的靜態類型編程語言 (靜態語言需要提前編譯&#xff0c;如&#xff1a;Java、c、c 等&#xff0c;動態語言如&#xff1a;js)Scala 是一門多范式的編程…

【介紹下Pwn,什么是Pwn?】

&#x1f308;個人主頁: 程序員不想敲代碼啊 &#x1f3c6;CSDN優質創作者&#xff0c;CSDN實力新星&#xff0c;CSDN博客專家 &#x1f44d;點贊?評論?收藏 &#x1f91d;希望本文對您有所裨益&#xff0c;如有不足之處&#xff0c;歡迎在評論區提出指正&#xff0c;讓我們共…

CSS3文字與字體

文字與字體 @font-face 用途:定義一種自定義字體,使其可以在網頁中使用。通過@font-face規則,可以指定字體名稱、來源(通常是URL)以及字體的各種變體(如常規、粗體、斜體等)。 @font-face {font-family: MyCustomFont;src: url(mycustomfont.woff2) format(woff2

馮喜運:5.25黃金價格和原油價格加速看跌?未來如何走勢?

【黃金消息面分析】&#xff1a;本周黃金市場經歷劇烈波動&#xff0c;金價創下五個半月來最糟糕的單周表現&#xff0c;盡管周五因美元下跌小幅回升。美聯儲的鷹派立場和美國經濟數據強勁削弱了降息預期&#xff0c;導致金價承壓。然而&#xff0c;分析師對未來金價走勢看法不…

Rolla‘s homework:Image Processing with Python Final Project

對比學習Yolo 和 faster rcnn 兩種目標檢測 要求 Image Processing with Python Final Project Derek TanLoad several useful packages that are used in this notebook:Image Processing with Python Final Project Project Goals: ? Gain an understanding of the object …

leetcode 1049.最后一塊石頭的重量II

思路&#xff1a;01背包 其實這道題我們可以轉化一下&#xff0c;乍一看有點像區間dp&#xff0c;很像區間合并那種類型。 但是&#xff0c;后來發現&#xff0c;這道題的精髓在于你如何轉成背包問題。我們可以把這個石頭分成兩堆&#xff0c;然后求出來這兩堆的最小差值就行…

使用git生成SSH公鑰,并設置SSH公鑰

1、在git命令行里輸入以下命令 ssh-keygen -t rsa 2、按回車&#xff0c;然后會看到以下字眼 Generating public/private rsa key pair. Enter file in which to save the key (/c/Users/xxx/.ssh/id_rsa) 例&#xff1a; 3、繼續回車&#xff0c;然后會看到以下字眼 Enter…

【面試干貨】數據庫樂觀鎖,悲觀鎖的區別,怎么實現

【面試干貨】數據庫樂觀鎖&#xff0c;悲觀鎖的區別&#xff0c;怎么實現 1、樂觀鎖&#xff0c;悲觀鎖的區別2、總結 &#x1f496;The Begin&#x1f496;點點關注&#xff0c;收藏不迷路&#x1f496; 1、樂觀鎖&#xff0c;悲觀鎖的區別 悲觀鎖&#xff08;Pessimistic Lo…

web前端框架設計第十課-組件

web前端框架設計第十課-組件 一.預習筆記 組件&#xff1a;Vue最強大的功能之一 1.局部組件注冊 注意事項&#xff1a;template標簽中只能有一個根元素 2.全局組件的注冊 注意事項&#xff1a;組件名的大小寫需要注意&#xff08;實踐&#xff09; 3.案例&#xff08;查詢框…

Vivado 使用教程(個人總結)

Vivado 是 Xilinx 公司推出的一款用于 FPGA 設計的集成開發環境 (IDE)&#xff0c;提供了從設計輸入到實現、驗證、調試和下載的完整流程。本文將詳細介紹 Vivado 的使用方法&#xff0c;包括項目創建、設計輸入、約束文件、綜合與實現、仿真、調試、下載配置等步驟。 一、創建…

設計模式--責任鏈模式

責任鏈模式是一種行為設計模式&#xff0c;它允許將請求沿著處理者鏈進行發送。請求會沿鏈傳遞&#xff0c;直到某個處理者對象負責處理它。這種模式在許多應用場景中非常有用&#xff0c;例如在處理用戶輸入、過濾請求以及實現多級審核時。 應用場景 處理用戶輸入&#xff1…

kafka之consumer參數auto.offset.reset

Kafka的auto.offset.reset 參數是用于指定消費者在啟動時如何處理偏移量&#xff08;offset&#xff09;的。這個參數有三個主要的取值&#xff1a;earliest、latest和none。 earliest&#xff1a; 當各分區下有已提交的offset時&#xff0c;從提交的offset開始消費&#xff1b…

HCIP-VLAN綜合實驗

一、實驗拓撲 二、實驗要求 1、pc1和pc3所在接口為access;屬于vlan 2; PC2/PC4/PC5/PC6處于同一網段’其中PC2可以訪問PC4/PC5/PC6; PC4可以訪問PC6&#xff1b;PC5不能訪問PC6&#xff1b; 2、PC1/PC3與PC2/PC4/PC5/PC6不在同一個網段&#xff1b; 3、所有PC通過DHCP獲取IP…

棧和隊列的應用-計算器實例

‘’‘ &#xff08;11 3&#xff09; 2 -5 順序存儲棧來實現 ’‘’ sqstack.h #ifndef SQSTACK_H__ #define SQSTACK_H__ #define MAXSIZE 32 typedef int datatype typedef struct node_st {datatype data[MAXSIZE]; int top;}sqstack;sqstack *st_create(void); int s…

閑話 .NET(5):.NET Core 有什么優勢?

前言 .NET Core 并不是 .NET FrameWork 的升級版&#xff0c;它是一個為滿足新一代的軟件設計要求而從頭重新開發的開發框架和平臺&#xff0c;所以它沒有 .NET FrameWork 的歷史包袱&#xff0c;相對于 .NET FrameWork&#xff0c;它具備很多優勢。 .NET Core 有哪些優勢&am…

智算中心帶寬漫談 -- 開篇

隱秘的角落 帶寬對高性能計算是一個永恒的話題&#xff0c;本質上&#xff0c;帶寬即數據交換的速率&#xff0c;單位時間的傳輸數據越多&#xff0c;帶寬就越高&#xff0c;但對高性能計算來說&#xff0c;對高帶寬的渴求永無止境&#xff0c;好比宏觀現實世界中的車道&#…

QT實現線程的四種方式(QThread、QRunnable和QThreadPool、QObject、QtConcurrent)

在當今高性能計算需求日益增長的背景下,多線程編程已成為提升應用性能的重要手段。Qt框架,作為一個功能全面、跨平臺的C++應用程序開發工具包,為我們提供了多種多線程實現方案。本文將介紹QThread類在Qt多線程編程中的應用,以及如何通過QRunnable和QThreadPool、QObject的m…

C# GDI+ 繪制文字不同的操作系統渲染文字大小不同

一、C# GDI 繪制文字不同的操作系統渲染文字大小不同 原因&#xff1a;使用Font 字體的時候&#xff0c;沒有指定字體渲染的單位。 不同系統的默認字體單位會不同。 二、解決方案&#xff1a; 在指定字體的時候&#xff0c;指定字體大小&#xff0c;同時也要設置字體的單位 …