主頁 > 移動端開發 > Kotlin協程-從一到多

Kotlin協程-從一到多

2023-06-17 08:16:25 移動端開發

上一篇文章,我介紹了Kotlin協程的創建,使用,協作等內容,本篇將引入更多的使用場景,繼續帶你走進協程世界,

使用協程處理異步資料流

常用編程語言都會內置對同一型別不同物件的資料集表示,我們通常稱之為容器類,不同的容器類適用于不同的使用場景,Kotlin的Flow就是在異步計算的需求下引入的,用于表示異步的資料流,

Flow

“問渠哪得清如許,為有源頭活水來”,異步資料流的基本就是以某種方式獲得異步資料,Kotlin提供了多種種方式,比較常用的就是Kotlin協程包的asFlow擴展和flow構造器,前者是對普通資料集的Flow化封裝,沒有更多可言,我們著重來看后者,
flow構造器的主要目標就是產生一個異步資料流,它是一個泛型函式,引數是一個掛起函式,并且是FlowCollector是擴展函式,這個介面只有一個emit方法,就是為創建的Flow提供異步計算的資料的,因為它是掛起函式,所以我們能在里面使用其他掛起函式計算異步值,然后通過emit方法將值發送出去,如此反復就能為下游操作提供源源不斷的資料流了,
事情還沒完,上面的步驟我們只是規定了創建資料的方式,并沒有真正執行,也就是建好了道路,但是還沒有車上路,那么,怎樣才能讓車在路上跑呢,查看Flow的介面會發現,它提供了collect方法來處理資料,collect接收一個掛起函式作為處理邏輯,但是同時,collect方法本身也是掛起函式,所以,這個方法只能在掛起函式中運行,有了這些知識,我們就可以寫出最簡單的異步資料流了,

 1uspend fun compute():Int{
             delay(123)
             return 1024
 }
 
 viewModelScope.launch {
     val flow=flow<Int> {
         emit(9527)
         emit(compute())
        delay(256)
        emit(256)
    }
    flow.collect {
        println(it)
    }
}

flow構造器里面隨意做各種操作,只要在必要的時候傳遞結果就行了,但是需要注意的是,emit方法只能運行在同一個協程里,乍一看,這樣分開寫和寫在一起并沒有本質上的差別,但Flow還能做到更多,

該給Flow換個作業環境了

上一節,我們那個簡單的示例,假如把構造器里面的資料獲取方法換成網路請求,應用就歇菜了,因為它們都是運行在主執行緒里面的,那么這個時候,看過上一篇文章的小伙伴馬上就會反應過來,用withContext方法在構造器里面切換執行緒就行了哇,思路是很對,因為Flow的默認配置就是構造器和collect方法作業在同一執行緒,既然現在主執行緒不讓運行,那就把構造器的執行緒切換一下就行了唄,然后事實并不是這樣,這樣寫出來的代碼根本無法運行,因為官方提供了唯一的flowOn方法來切換構造器的執行執行緒,使用也很簡單,就是對創建好的Flow物件配置一次flowOn方法就行了,

val flow=["1.jpg","2.jpg"].asFlow()
flow.map { decode(it) }
        .flowOn(Dispatchers.IO)
viewModelScope.launch {
    flow.collect{
        adapter.add(it)
    }

有些中間處理邏輯

熟悉RxJava的小伙伴可能有疑問了,這些操作RxJava也能完成,甚至還有更多的運算子來支持中間狀態的處理,那么異步資料流能做到這些嗎,毫無疑問,它可以,普通的資料集有map,filter等操作方法,對于異步資料流來說,這些方法同樣適用,而且這些方法引數都是掛起函式,都可以執行異步操作,而且它還有個更靈活的transform方法,這個方法可以定制自己的運算子,實作更靈活的資料操作,

當然,上面那些運算子都只能實作單一異步流的操作,對于多資料流的支持,它也同樣不在話下,zip可以將兩個兩個資料源兩兩合并起來,合成的資料流長度為兩個資料流中最短的那個資料流的長度,combine則與zip不同,它會將兩個資料流最近的發送資料作為輸入,也就是說,假如一塊一慢的兩個資料源,慢的資料源的元素可能會被多次取到,從而最終的資料流比最短的那個都長,

val flow = flowOf(1, 2).delayEach(10)
val flow2 = flowOf("a", "b", "c").delayEach(15)
flow.combine(flow2) { i, s -> i.toString() + s }.collect {
     println(it) // Will print "1a 2a 2b 2c"
}

結束狀態跟蹤

上一節提到,由于資料源和處理邏輯不在同一個地方,所以很難確定最終的資料流大小,進而不知道資料流什么時候處理結束,而且中間操作也可能會改變資料流的大小,由此就更加難以確定資料處理結束的時機了,但是我們有的時候卻需要在資料處理完成后做一些操作,該怎么辦呢?這個時候當然是該onCompletion方法上場了,這個方法有一個可為空的Throwable型別引數,很顯然,這可以同時指示兩種處理結果,成功或者失敗,失敗就會將例外物件傳遞進來,

多個協程共同作業

很多時候,避免不了讓多個協程共同作業,對于回傳單個值的協程,上一篇我們也提到過了,可以傳遞async構造器的回傳物件Deferred,但是局限性就是這個物件只能傳遞一個值,針對多值傳遞的情況,Kotlin提供了Channel的解決方法,Channel類似于阻塞佇列,資料通過send方法發送出去,在另外的地方使用receive方法接收,通過這種方法,我們可以極大提供協程的作業效率,利用它就可以輕松實作生產者和消費者模型,

 val chanel=Channel<Int>()
 viewModelScope.launch(Dispatchers.IO) {
     for (i in 1..5){
         delay(1000)
         chanel.send(i)
     }
 }
 viewModelScope.launch { 
     for (i in chanel){
        println("Handle ${i}")
    }
}

當然,這只是最簡單的用法,還可以加入更多的生產者,或者不再需要資料時取消,甚至還有專門的product構造器,直接獲得回傳多個值的協程物件,

總結

Kotlin協程有很多有用的API,這些API覆寫了大部分異步使用的場景,所以在使用協程的時候,我們首先需要明確使用場景,再根據使用場景確定使用哪一套API,這可以使我們避免陷入API恐懼癥,為此,我根據這兩篇文章的內容,整理出了一份情景表格,實際開發中可以參照使用,
Kotlin協程構造器

API 使用場景
launch 執行耗時操作,不需要回傳值
async 需要獲取耗時操作的單個回傳值
produce 需要獲取耗時操作的多個回傳值

Kotlin協程協同工具

API 使用場景
Flow 操作異步資料流
Channel 協程間通信

青山不改,綠水長流,咱們下期見!

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/555428.html

標籤:其他

上一篇:【有獎調研】HarmonyOS新物種,鴻蒙流量新陣地——元服務邀你來答題!

下一篇:返回列表

標籤雲
其他(161177) Python(38236) JavaScript(25504) Java(18244) C(15237) 區塊鏈(8271) C#(7972) AI(7469) 爪哇(7425) MySQL(7256) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5875) 数组(5741) R(5409) Linux(5347) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4601) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2436) ASP.NET(2404) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) .NET技术(1984) HtmlCss(1968) 功能(1967) Web開發(1951) C++(1941) python-3.x(1918) 弹簧靴(1913) xml(1889) PostgreSQL(1881) .NETCore(1863) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【從零開始擼一個App】Dagger2

    Dagger2是一個IOC框架,一般用于Android平臺,第一次接觸的朋友,一定會被搞得暈頭轉向。它延續了Java平臺Spring框架代碼碎片化,注解滿天飛的傳統。嘗試將各處代碼片段串聯起來,理清思緒,真不是件容易的事。更不用說還有各版本細微的差別。 與Spring不同的是,Spring是通過反射 ......

    uj5u.com 2020-09-10 06:57:59 more
  • Flutter Weekly Issue 66

    新聞 Flutter 季度調研結果分享 教程 Flutter+FaaS一體化任務編排的思考與設計 詳解Dart中如何通過注解生成代碼 GitHub 用對了嗎?Flutter 團隊分享如何管理大型開源專案 插件 flutter-bubble-tab-indicator A Flutter librar ......

    uj5u.com 2020-09-10 06:58:52 more
  • Proguard 常用規則

    介紹 Proguard 入口,如何查看輸出,如何使用 keep 設定入口以及使用實體,如何配置壓縮,混淆,校驗等規則。

    ......

    uj5u.com 2020-09-10 06:59:00 more
  • Android 開發技術周報 Issue#292

    新聞 Android即將獲得類AirDrop功能:可向附近設備快速分享檔案 谷歌為安卓檔案管理應用引入可安全隱藏資料的Safe Folder功能 Android TV新主界面將顯示電影、電視節目和應用推薦內容 泄露的Android檔案暗示了傳說中的谷歌Pixel 5a與折疊屏新機 谷歌發布Andro ......

    uj5u.com 2020-09-10 07:00:37 more
  • AutoFitTextureView Error inflating class

    報錯: Binary XML file line #0: Binary XML file line #0: Error inflating class xxx.AutoFitTextureView 解決: <com.example.testy2.AutoFitTextureView android: ......

    uj5u.com 2020-09-10 07:00:41 more
  • 根據Uri,Cursor沒有獲取到對應的屬性

    Android: 背景:呼叫攝像頭,拍攝視頻,指定保存的地址,但是回傳的Cursor檔案,只有名稱和大小的屬性,沒有其他諸如時長,連ID屬性都沒有 使用 cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATIO ......

    uj5u.com 2020-09-10 07:00:44 more
  • Android連載29-持久化技術

    一、持久化技術 我們平時所使用的APP產生的資料,在記憶體中都是瞬時的,會隨著斷電、關機等丟失資料,因此android系統采用了持久化技術,用于存盤這些“瞬時”資料 持久化技術包括:檔案存盤、SharedPreference存盤以及資料庫存盤,還有更復雜的SD卡記憶體儲。 二、檔案存盤 最基本存盤方式, ......

    uj5u.com 2020-09-10 07:00:47 more
  • Android Camera2Video整合到自己專案里

    背景: Android專案里呼叫攝像頭拍攝視頻,原本使用的 MediaStore.ACTION_VIDEO_CAPTURE, 后來因專案需要,改成了camera2 1.Camera2Video 官方demo有點問題,下載后,不能直接整合到專案 問題1.多次拍攝視頻崩潰 問題2.雙擊record按鈕, ......

    uj5u.com 2020-09-10 07:00:50 more
  • Android 開發技術周報 Issue#293

    新聞 谷歌為Android TV開發者提供多種新功能 Android 11將自動填表功能整合到鍵盤輸入建議中 谷歌宣布Android Auto即將支持更多的導航和數字停車應用 谷歌Pixel 5只有XL版本 搭載驍龍765G且將比Pixel 4更便宜 [圖]Wear OS將迎來重磅更新:應用啟動時間 ......

    uj5u.com 2020-09-10 07:01:38 more
  • 海豚星空掃碼投屏 Android 接收端 SDK 集成 六步驟

    掃碼投屏,開放網路,獨占設備,不需要額外下載軟體,微信掃碼,發現設備。支持標準DLNA協議,支持倍速播放。視頻,音頻,圖片投屏。好點意思。還支持自定義基于 DLNA 擴展的操作動作。好像要收費,沒體驗。 這里簡單記錄一下集成程序。 一 跟目錄的build.gradle添加私有mevan倉庫 mave ......

    uj5u.com 2020-09-10 07:01:43 more
最新发布
  • Kotlin協程-從一到多

    > 上一篇文章,我介紹了Kotlin協程的創建,使用,協作等內容。本篇將引入更多的使用場景,繼續帶你走進協程世界。 ### 使用協程處理異步資料流 常用編程語言都會內置對同一型別不同物件的資料集表示,我們通常稱之為容器類。不同的容器類適用于不同的使用場景。Kotlin的`Flow`就是在異步計算的需 ......

    uj5u.com 2023-06-17 08:16:25 more
  • 【有獎調研】HarmonyOS新物種,鴻蒙流量新陣地——元服務邀你來答

    “聊技術無話不談,一起來吹吹元服務!暢聊你對元服務的想法,說不定,你就能撬動元服務的爆發增長!” 元服務(即原子化服務)是華為“輕量化”服務的新物種,可提供全新的服務和互動方式,讓應用化繁為簡,讓服務觸手可及!基于鴻蒙萬能卡片,元服務可實作應用功能在桌面“永遠打開”,實作智能推薦、服務直達! 而在元 ......

    uj5u.com 2023-06-17 08:16:19 more
  • Kotlin協程-從理論到實戰

    > 上一篇文章從理論上對Kotlin協程進行了部分說明,本文將在上一篇的基礎上,從實戰出發,繼續協程之旅。 ### 從源頭說起 在Kotlin中,要想使用協程,首先需要使用協程創建器創建,但還有個前提——協程作用域(`CoroutineScope`)。在早期的Kotlin實作中,協程創建器是一等函式 ......

    uj5u.com 2023-06-17 08:15:56 more
  • Kotlin協程-從一到多

    > 上一篇文章,我介紹了Kotlin協程的創建,使用,協作等內容。本篇將引入更多的使用場景,繼續帶你走進協程世界。 ### 使用協程處理異步資料流 常用編程語言都會內置對同一型別不同物件的資料集表示,我們通常稱之為容器類。不同的容器類適用于不同的使用場景。Kotlin的`Flow`就是在異步計算的需 ......

    uj5u.com 2023-06-17 08:15:51 more
  • 【有獎調研】HarmonyOS新物種,鴻蒙流量新陣地——元服務邀你來答

    “聊技術無話不談,一起來吹吹元服務!暢聊你對元服務的想法,說不定,你就能撬動元服務的爆發增長!” 元服務(即原子化服務)是華為“輕量化”服務的新物種,可提供全新的服務和互動方式,讓應用化繁為簡,讓服務觸手可及!基于鴻蒙萬能卡片,元服務可實作應用功能在桌面“永遠打開”,實作智能推薦、服務直達! 而在元 ......

    uj5u.com 2023-06-16 08:48:47 more
  • 100個物聯網專案(基于ESP32)1ESP32的基礎

    ## 1-NodeMCU、ESP32的基礎 ### 簡介 NodeMCU是一個開源的IoT(物聯網)平臺,包括在樂鑫的ESP8266 Wi-Fi SoC上運行的韌體和基于ESP-12模塊的硬體。它是由一樂鑫在2014年創建的,他們希望為物聯網專案提供低成本和靈活的平臺。ESP32是低成本的微芯片,具 ......

    uj5u.com 2023-06-16 08:30:36 more
  • 推送服務接入指導(HarmonyOS篇)

    訊息推送作為App運營日常使用的用戶促活和召回手段,是與用戶建立持續互動和連接的良好方式。[推送服務](https://developer.huawei.com/consumer/cn/hms/huawei-pushkit?ha_source=hms1)(Push Kit)是華為提供的訊息推送平臺, ......

    uj5u.com 2023-06-16 08:30:25 more
  • Kotlin協程-那些理不清亂不明的關系

    > Kotlin的協程自推出以來,受到了越來越多Android開發者的追捧。另一方面由于它龐大的API,也將相當一部分開發者拒之門外。本篇試圖從協程的幾個重要概念入手,在復雜API中還原出它本來的面目,以全新的角度帶讀者走進Kotlin協程世界。 ### 什么是協程 在很多有關協程的文章中,描述協程 ......

    uj5u.com 2023-06-16 08:30:20 more
  • 社交直播語聊場景解決方案(一)商業化探索

    在過去幾年的直播行業創業風口期中,直播的用戶關注度瘋狂增長,但用戶質量卻參差不齊。隨著用戶新鮮感一過,流失率變得相當嚴重,各大平臺都在竭盡全力防御。然而,留住“湊熱鬧”的非直播受眾用戶并不是最關鍵的問題,而是要找到適合真實直播受眾用戶的商業化道路,才能保證行業的穩定繁榮。因此,我們需要探索有效的商業... ......

    uj5u.com 2023-06-16 08:30:15 more
  • WWDC2023 Session系列:探索XCode15新特性

    ![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/44a0e0fd567c4421bc94be83e84f6dce~tplv-k3u1fbpfcp-zoom-1.image) ## 一、版本說明 XCode 15 beta 發布于 2023 ......

    uj5u.com 2023-06-16 08:30:11 more