[Android]在后臺線程執行耗時操作,然后在主線程更新UI

1.Coroutines(官方推薦)

Coroutines 提供了一種輕量級的線程管理方式,使得在后臺線程執行任務和在主線程更新 UI 變得簡單。以下是如何在 Kotlin 中使用 Coroutines 來處理耗時邏輯并更新 UI 的步驟:

添加 Coroutines 依賴:

首先,確保你的 Android 項目中包含了 Coroutines 的依賴。在你的?build.gradle?文件中添加:

implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1")

版本查詢:Maven Central

使用?CoroutineScope?啟動協程:

你可以在 Activity 或 Fragment 中通過定義一個 CoroutineScope 來啟動協程。通常,在 Android 中,我們使用?lifecycleScope?(對于 Activities 和 Fragments)或?viewModelScope?(在 ViewModel 中)來自動管理協程的生命周期。

import kotlinx.coroutines.*class MyActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_my)lifecycleScope.launch {performLongRunningTask()}}private suspend fun performLongRunningTask() {// 運行在后臺線程withContext(Dispatchers.IO) {// 模擬耗時操作Thread.sleep(2000)// 計算或數據處理}// 更新 UI 必須在主線程執行withContext(Dispatchers.Main) {// 更新 UI 組件findViewById<TextView>(R.id.textView).text = "Update completed"}}
}

在這個例子中,performLongRunningTask?函數使用?withContext(Dispatchers.IO)?來指定代碼塊應該在 IO 調度器(通常用于磁盤和網絡操作的線程池)上運行。耗時操作完成后,使用?withContext(Dispatchers.Main)?切換回主線程來更新 UI。

2.runOnUiThread

runOnUiThread?是?Activity?類中的一個方法,它被用來確保一段代碼塊在主線程(也稱為 UI 線程)上執行。這是處理 UI 更新的一種常見方法,特別是當你在后臺線程中完成一些處理,并需要將結果安全地更新到 UI 上時。

使用示例:

class MyActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_my)Thread {// 執行一些耗時的任務val result = performLongRunningTask()// 現在需要更新UIrunOnUiThread {// 這部分代碼在主線程執行,可以安全地更新UIfindViewById<TextView>(R.id.textView).text = result}}.start()}private fun performLongRunningTask(): String {// 模擬耗時操作Thread.sleep(2000)return "Operation Completed"}
}

工作機制:

  • 當你從非 UI 線程調用?runOnUiThread?方法時,它將傳入的 Runnable 對象排隊到主線程的消息隊列中。主線程將在處理其他 UI 任務時,按順序處理這些消息。

  • 如果?runOnUiThread?是在主線程本身調用的,那么 Runnable 將被立即執行。

使用場景和注意事項:

使用場景

當你在后臺線程中完成任務后需要在 UI 上顯示結果時,可以使用?runOnUiThread。例如,在網絡請求完成后更新界面。

注意事項

保證只在需要修改 UI 的時候使用?runOnUiThread,避免在主線程上執行耗時的操作,這樣可以避免界面卡頓。

雖然?runOnUiThread?是一個方便的工具,但在處理復雜的異步邏輯時,使用 Kotlin Coroutines 或 RxJava 可能是更好的選擇,因為它們提供了更好的控制機制和錯誤處理能力。

3.RxJava

RxJava?是一個在 Java VM 上使用可觀測序列來組成異步和基于事件的程序的庫,它非常適合用于復雜的線程操作和數據流處理。

import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.schedulers.SchedulersObservable.fromCallable {// 在后臺線程執行耗時操作Thread.sleep(2000)"Operation Completed"
}
.subscribeOn(Schedulers.io())? // 指定上游操作在 IO 線程
.observeOn(AndroidSchedulers.mainThread())? // 指定下游操作在主線程
.subscribe { result ->textView.text = result? // 更新 UI
}

4.Handler

Handler?是 Android 中處理線程間通信的一種方式,尤其適用于從后臺線程發送數據到主線程。

val handler = Handler(Looper.getMainLooper())Thread {// 執行耗時操作Thread.sleep(2000)? // 模擬耗時操作val message = "Operation Completed"// 使用 Handler 切回主線程handler.post {textView.text = message}
}.start()

5.AsyncTask(deprecated)

AsyncTask?是 Android 提供的一個抽象類,用于處理后臺任務并在主線程上發布結果。不過,需要注意的是,從 Android API level 30 開始,AsyncTask?已被標記為過時(deprecated),因為它不推薦用于現代 Android 開發。盡管如此,了解它的使用仍然對理解 Android 異步編程模型有幫助。

class MyAsyncTask(private val textView: TextView) : AsyncTask<Void, Void, String>() {override fun doInBackground(vararg params: Void?): String {// 在后臺線程執行耗時操作Thread.sleep(2000)? // 模擬耗時操作return "Operation Completed"}override fun onPostExecute(result: String) {// 在主線程更新 UItextView.text = result}
}// 在 Activity 或 Fragment 中使用
MyAsyncTask(textView).execute()

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

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

相關文章

數據結構·一篇搞定隊列!

hello&#xff0c;大家好啊&#xff0c;肖恩又拖更了&#xff0c;你們聽我狡辯&#xff0c;前段時間有期中考試&#xff0c;so我就沒什么時間寫這個&#xff0c;在這給大家道個歉&#x1f62d;&#x1f62d;&#x1f62d; 我后面一定盡力不拖更 那么接下來&#xff0c;我們來看…

Greenplum使用hbase外部表

概述 GP可以通過pxf協議上的hbase外表功能&#xff0c; 在數據庫中創建外部表&#xff0c;映射hbase table&#xff0c;以直接在gp中訪問 hbase數據&#xff0c;方便將hbase的查詢結果集保留在gp中 hbase端準備 HBase基礎概念&#xff1a; ?HBase 列包含兩個組件&#xff1…

粒子輻照環境中相機鏡頭防護及LabVIEW圖像處理注意事項

在粒子輻照環境測試電路板性能的實驗中&#xff0c;需要對相機鏡頭進行有效防護&#xff0c;同時利用LabVIEW進行圖像識別和處理。本文將討論相機鏡頭防護的關鍵因素和LabVIEW處理過程中的注意事項&#xff0c;包括防輻射材料選擇、輻射屏蔽措施、散熱管理、空間布局及LabVIEW軟…

c++11:左值引用和右值引用《全家桶》

總結一下C11中涉及到左值引用和右值引用的場景。 1 左值引用和右值引用的區別 左值引用 定義&#xff1a;對左值的引用。目的是避免內存拷貝&#xff0c;類似c中的指針,兩個場景&#xff1a;函數傳參、函數返回值。 右值引用 定義&#xff1a;對右值的引用。兩個場景&#…

【機器學習-k近鄰算法-01】 | Scikit-Learn工具包進階指南:機器學習sklearn.neighbors模塊之k近鄰算法實戰

&#x1f3a9; 歡迎來到技術探索的奇幻世界&#x1f468;?&#x1f4bb; &#x1f4dc; 個人主頁&#xff1a;一倫明悅-CSDN博客 ?&#x1f3fb; 作者簡介&#xff1a; C軟件開發、Python機器學習愛好者 &#x1f5e3;? 互動與支持&#xff1a;&#x1f4ac;評論 &…

騎行 - 新區永旺出發的環太湖路線

環過好幾次太湖&#xff0c;但對路線都沒太在意&#xff0c;都是跟著別人走的。這次自己制定一個路書&#xff0c;方便下次自己一個人環太湖時使用。 開始是使用高德地圖做路書&#xff0c;只能在PC上做。我用的是網頁版&#xff0c;每次選點太麻煩了。要輸入地址搜索&#xff…

開源博客項目Blog .NET Core源碼學習(27:App.Hosting項目結構分析-15)

本文學習并分析App.Hosting項目中后臺管理頁面的角色管理頁面。 ??角色管理頁面用于顯示、檢索、新建、編輯、刪除角色數據同時支持按角色分配菜單權限&#xff0c;以便按角色控制后臺管理頁面的菜單訪問權限。角色管理頁面附帶一新建及編輯頁面&#xff0c;以支撐新建和編輯…

電纜廠可視化:提升生產透明度與運營效率

圖撲電纜廠可視化系統通過實時監控和數據分析&#xff0c;提高生產過程的透明度和可控性&#xff0c;優化資源配置和質量管理&#xff0c;顯著提升運營效率和產品質量。

啟動SpringBoot項目及解決端口占用問題(指令版)

打包SpringBoot 項目 需要將 SpringBoot 項目進行打包。可以使用 Maven 的快捷工具&#xff0c;或者在項目的 pom.xml 文件所在目錄執行以下命令&#xff1a; mvn clean package部署注意 Windows系統下&#xff0c;按照以下方式在cmd窗口以管理員身份允許使用命令啟動spring…

Flutter 中的 StatefulBuilder 小部件:全面指南

Flutter 中的 StatefulBuilder 小部件&#xff1a;全面指南 在Flutter中&#xff0c;StatefulBuilder是一個高效的小部件&#xff0c;它根據給定的構建函數來構建widget&#xff0c;并在組件樹中只對需要重新構建的部分進行更新。這使得它在性能優化方面非常有用&#xff0c;特…

電子電器架構 - AUTOSAR ON THE AIR

電子電器架構 - AUTOSAR ON THE AIR 我是穿拖鞋的漢子,魔都中堅持長期主義的汽車電子工程師。 老規矩,分享一段喜歡的文字,避免自己成為高知識低文化的工程師: 屏蔽力是信息過載時代一個人的特殊競爭力,任何消耗你的人和事,多看一眼都是你的不對。非必要不費力證明自己…

Mybase長久破解

1、軟件下載好之后&#xff0c;找到文件mybase8.ini文件 2、使用記事本打開&#xff0c;通過 Ctrl F 輸入快速找到屬性設置FirstUseOn.UserLic.App&#xff0c;將等號后面的數值刪掉保存即可 3、使用防護中心–>自定義防護&#xff08;記得開啟&#xff09; 4、添加規則…

Golang文件操作

文章目錄 文件操作基本介紹普通的文件操作方式&#xff08;os包&#xff09;帶緩沖的文件操作方式&#xff08;bufio包&#xff09;文件拷貝操作&#xff08;io包&#xff09; 命令行參數基本介紹解析命令行參數&#xff08;flag包&#xff09; JSON基本介紹JSON序列化JSON反序…

【MySQL精通之路】MySQL的使用(3)-連接到服務器的配置

目錄 1.連接建立的命令選項 1.1.--default-auth 1.2.--hosthost_name, -h host_name 1.3.--password[pass_val], -p[pass_val] 1.4.--password1[pass_val] 1.5.--password2[pass_val] 1.6.--password3[pass_val] 1.7.--pipe, -W 1.8.--plugin-dirdir_name 1.9.--port…

【YOLOv10訓練】:報錯 AttributeError: ‘str‘ object has no attribute ‘view‘ 解決方法

YOLOv10訓練報錯 YOLOv10是在YOLOv8基礎上修改的&#xff0c;即&#xff1a;訓練方法和過程是相同的。 但按照v8訓練程序train.py&#xff0c;如下所示&#xff0c;直接訓練&#xff1a; from ultralytics import YOLO# Load a model model YOLO("ultralytics/cfg/mod…

真拿AI賺到錢的人,不在朋友圈里

1 最近有張兩大AI巨頭對比的梗圖給我看樂了&#xff0c;玩兒AI的還在做產品&#xff0c;玩兒焦慮的已經在數錢了。 這也是在做AI&#xff0c;只不過是唉聲嘆氣的ai。 要我說&#xff0c;現在缺的根本不是AI&#xff0c;而是【有用的AI】。 恩格斯老師說過一句話&#xff1a…

科林Linux6_網絡

#include<sys/socket.h> #include<arpa/inet.h> //大小端轉換 #include<netdb.h> //DNS一、Socket套接字 為了開發網絡應用&#xff0c;系統提供一套API函數接口&#xff0c;用于網絡應用開發&#xff0c;這些接口稱為套接字函數 struct sockaddr_in…

數據庫管理-第194期 網絡加速RDMA初探(20240526)

數據庫管理194期 2024-05-26 數據庫管理-第194期 網絡加速RDMA初探&#xff08;20240526&#xff09;1 概念2 發展3 使用總結 數據庫管理-第194期 網絡加速RDMA初探&#xff08;20240526&#xff09; 作者&#xff1a;胖頭魚的魚缸&#xff08;尹海文&#xff09; Oracle ACE A…

英文 海量的學習句子比單獨的記單詞效果要好,格句致知。

英文 海量的學習句子比單獨的記單詞效果要好 句子有上下文、場景和時態等&#xff0c;能形成劇情&#xff0c;變得生動有趣。 如果一句沒聽懂&#xff0c;還繼續聽就是浪費時間了。要一句一句地深究&#xff0c;不然就要讀好幾遍&#xff0c;還得背誦。要深入理解&#xff0c…

不同的二叉搜索樹(II)題解

toc &#x1f91a;我的博客 歡迎光臨我的博客&#xff1a;https://blog.csdn.net/qq_52434217?typeblog &#x1f95b;前言 動態規劃是常見的算法思路&#xff0c;動態規劃在計算過程中保存了部分計算結果到內存中&#xff0c;以便于在進行下一次計算時可以直接從內存中獲…