Android 中的多線程編程全面解析

Android 中的多線程編程全面解析

一、Android 線程模型基礎

主線程(UI 線程)特性

  • 唯一性:每個應用只有一個主線程
  • 職責:處理 UI 操作和用戶交互
  • 限制:禁止在主線程執行耗時操作(超過5秒會導致 ANR)
  • 檢查方法Looper.getMainLooper().thread == Thread.currentThread()

工作線程使用原則

  • 網絡請求:必須在工作線程執行
  • 文件IO:超過毫秒級的操作應放在工作線程
  • 數據庫操作:Room 默認提供異步支持,復雜查詢仍需工作線程
  • 計算密集型任務:如加密、圖像處理等

二、Android 多線程方案演進

1. 基礎方案

// 基本線程創建
Thread {// 后臺操作runOnUiThread {// 更新UI}
}.start()

2. Executor 框架(推薦基礎方案)

val executor = Executors.newFixedThreadPool(4)
executor.execute {// 后臺任務
}

3. Android 特有機制

// HandlerThread 示例
val handlerThread = HandlerThread("MyHandlerThread").apply { start() }
val handler = Handler(handlerThread.looper)
handler.post {// 在后臺線程執行
}

三、現代協程解決方案(Kotlin Coroutines)

協程核心概念

  • 輕量級線程:數千協程可并行,開銷遠小于線程
  • 結構化并發:自動取消和資源清理
  • 掛起函數:用同步寫法實現異步操作

基本使用

// ViewModel 中啟動協程
viewModelScope.launch {// 主線程執行val data = withContext(Dispatchers.IO) {// 切換到IO線程執行網絡請求fetchDataFromNetwork()}// 自動切回主線程更新UIupdateUI(data)
}

關鍵組件

組件作用典型使用場景
Dispatchers.Main主線程更新UI
Dispatchers.IOIO密集型網絡/文件操作
Dispatchers.DefaultCPU密集型復雜計算
viewModelScope自動取消作用域ViewModel中的協程
lifecycleScope生命周期作用域Activity/Fragment中的協程

四、線程間通信機制

1. Handler/Looper 傳統方式

val mainHandler = Handler(Looper.getMainLooper())
Thread {// 后臺工作mainHandler.post {// 主線程更新UI}
}.start()

2. LiveData 自動線程切換

liveData.postValue(data) // 可從任何線程調用
liveData.observe(this) { data -> // 自動在主線程回調
}

3. Flow 響應式流

flow {emit(fetchData()) // 在IO線程發射數據
}
.map { compute(it) }  // 在Default線程轉換
.flowOn(Dispatchers.Default)
.collect { data ->    // 在主線程收集updateUI(data)
}

五、高級并發模式

1. 并發任務處理

// 并行執行多個請求
val deferred1 = async { fetchData1() }
val deferred2 = async { fetchData2() }
val result = deferred1.await() + deferred2.await()

2. 互斥與同步

val mutex = Mutex()
var sharedData = 0fun updateData() = runBlocking {mutex.withLock {sharedData++}
}

3. 超時控制

withTimeoutOrNull(3000) {fetchData() // 超過3秒自動取消
} ?: showTimeoutError()

六、性能優化與陷阱規避

最佳實踐

  1. 線程池配置

    // 根據CPU核心數優化線程池
    val cpuCount = Runtime.getRuntime().availableProcessors()
    val executor = ThreadPoolExecutor(cpuCount + 1,cpuCount * 2 + 1,30L, TimeUnit.SECONDS,LinkedBlockingQueue()
    )
    
  2. 避免內存泄漏

    lifecycleScope.launch {lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {flow.collect { data ->// 只在界面可見時處理數據}}
    }
    
  3. ANR 預防

    • 將超過100ms的操作移出主線程
    • 使用 StrictMode 檢測違規操作
    StrictMode.setThreadPolicy(StrictMode.ThreadPolicy.Builder().detectNetwork().penaltyLog().build())
    

常見陷阱

  1. 回調地獄

    // 錯誤示例
    fetchUser { user ->fetchProfile(user.id) { profile ->updateUI(user, profile) // 嵌套難以維護}
    }// 協程改造
    viewModelScope.launch {val user = fetchUserSuspend()val profile = fetchProfileSuspend(user.id)updateUI(user, profile)
    }
    
  2. 過度創建線程

    • 避免直接 new Thread(),應使用線程池
    • 協程不應執行阻塞操作(應用 withContext
  3. 并發修改異常

    // 錯誤示例
    val list = mutableListOf<Int>()
    (1..1000).forEach { i ->thread {list.add(i) // 可能崩潰}
    }// 正確方案
    val concurrentList = Collections.synchronizedList(mutableListOf<Int>())
    

七、調試與監控工具

  1. Android Studio Profiler

    • 查看線程狀態和CPU使用率
    • 檢測線程泄漏和阻塞
  2. StrictMode

    StrictMode.setVmPolicy(VmPolicy.Builder().detectLeakedClosableObjects().penaltyLog().build())
    
  3. 協程調試

    // 在調試模式下啟用協程名稱
    System.setProperty("kotlinx.coroutines.debug", "on")
    
  4. 自定義線程監控

    // 監控線程創建
    val threadFactory = ThreadFactory { r ->Thread(r).also { thread ->Log.d("ThreadMonitor", "Thread created: ${thread.name}")}
    }
    

Android 多線程編程已經從原始的 Thread+Handler 模式發展為以協程為核心的現代并發模型。開發者應當根據項目需求選擇合適方案,小型項目可使用 Executor + Handler,中大型項目推薦全面采用協程。無論采用何種方案,都需要注意線程安全、生命周期管理和性能優化,才能構建出響應迅速且穩定的 Android 應用。

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

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

相關文章

golang -gorm 增刪改查操作,事務操作

增刪改查 1. 插入數據// api func SaveUser(ctx *gin.Context) {result : &common.Result{}user : &dao.User{}err : ctx.ShouldBindJSON(&user)if err ! nil {ctx.JSON(http.StatusOK, result.Fail(400, "請使用json數據格式傳值"))return}// 調用驗證函…

大數據時代UI前端的智能化服務升級:基于用戶情境的主動服務設計

hello寶子們...我們是艾斯視覺擅長ui設計、前端開發、數字孿生、大數據、三維建模、三維動畫10年經驗!希望我的分享能幫助到您!如需幫助可以評論關注私信我們一起探討!致敬感謝感恩!一、引言&#xff1a;從 “被動響應” 到 “主動預判” 的 UI 服務革命當用戶在暴雨天打開外賣…

CUDA性能優化實戰:7個步驟讓并行歸約算法提升10倍效率

本文深入探討了一個經典的并行計算算法——并行歸約&#xff08;Parallel Reduction&#xff09;的性能優化過程&#xff0c;通過七個漸進式的優化步驟&#xff0c;展示了如何將算法性能提升至極致。這項研究基于Mark Harris在NVIDIA網絡研討會中提出的優化方法&#xff0c;在重…

詳解梯度消失和梯度爆炸(反向傳播)?

什么是梯度消失&#xff1f;梯度消失&#xff08;Gradient Vanishing&#xff09; 是指在訓練神經網絡時&#xff0c;反向傳播過程中計算得到的梯度&#xff08;用于更新參數的重要信息&#xff09;隨著網絡層數的增加而急劇減小&#xff0c;甚至趨近于零的現象。這會導致深層網…

端到端自動駕駛:挑戰與前沿

端到端自動駕駛&#xff1a;挑戰與前沿 End-to-End Autonomous Driving: Challenges and Frontiers 自動駕駛研究社區已見證了越來越多采用端到端算法框架的方法的快速增長&#xff0c;這些方法利用原始傳感器輸入生成車輛的運動規劃&#xff0c;而不是專注于諸如檢測和運動預測…

rust cargo 編譯雙架構的庫

這個錯誤表明你的 Rust 工具鏈沒有安裝 aarch64-apple-darwin 目標平臺。以下是完整的解決方案&#xff1a; 解決方案 ??安裝目標平臺?? (必須步驟) rustup target add aarch64-apple-darwin??驗證安裝?? (可選但推薦) rustup target list --installed # 應該能看到 aa…

Apache Shiro 框架詳解

文章目錄一、Shiro 核心功能二、Shiro 架構2.1 三層架構2.2 核心組件&#xff08;SecurityManager 內部&#xff09;三、核心流程詳解3.1 認證流程&#xff08;登錄&#xff09;流程步驟&#xff1a;認證流程序列圖&#xff1a;3.2 授權流程&#xff08;權限校驗&#xff09;流…

【保姆級喂飯教程】Windows下安裝Git Flow

目錄前言一、SourceTree二、Git for Windows (previously MSysGit)1. 下載補丁1.1 getopt.exe1.2 libintl3.dll1.3 libiconv2.dll1.4 安裝補丁2. 安裝Git Flow3. 測試3.1 初始化&#xff08;Initialize&#xff09;3.2 設置遠程3.3 創建分支3.4 功能開發3.5 功能提交3.6 推送分…

manifest.json只有源碼視圖沒其他配置

項目場景&#xff1a;提示&#xff1a;這里簡述項目相關背景&#xff1a;有時候我們從git上面拉下代碼&#xff0c;第一次運行時發現&#xff0c;沒運行項&#xff0c;再看manifest.json文件&#xff0c;就只有json文件&#xff0c;沒有其他配置項原因分析&#xff1a;提示&…

數據分析-名詞

一、網頁訪問數據指標1.IP &#xff08;Internet Protocol&#xff09;獨立IP 通常采用獨立IP數&#xff0c; 理論上指00:00-24:00內相同IP地址重復訪問只被計算一次。而不同的商業統計工具&#xff0c;縮短去 掉重復統計的時間&#xff0c;也是數據統計放大的一個常用套路。 &…

UDP屬于是一種什么服務器?

UDP是一種傳輸層協議&#xff0c;通常會被應用在計算機網絡中&#xff0c;為企業與用戶提供無連接的數據信息傳輸功能&#xff0c;與TCP協議相比較來說&#xff0c;UDP會更加的簡單但是UDP在可靠性方面沒有一定的保證&#xff0c;屬于是一種基于UDP協議進行通信的服務器。UDP服…

ARM單片機OTA解析(一)

文章目錄一、單片機燒寫程序的幾種方法二、Bootloader如何加載啟動App一、單片機燒寫程序的幾種方法 在線應用編程&#xff0c;由開發者實現Bootloader功能&#xff0c;比如ARM單片機的Code分區中的Flash本是存儲用戶應用程序的區間(上電從此處執行用戶代碼)&#xff0c;開發者…

C語言基礎教程--從入門到精通

C語言基礎教程–從入門到精通&#xff08;總體概括&#xff09; 接下來會對每一個章節進行詳細的總結與整理&#xff0c;希望對大家有用&#xff01;大家一起學習&#xff01; 目錄C語言基礎教程--從入門到精通&#xff08;總體概括&#xff09;**接下來會對每一個章節進行詳細…

單細胞分析教程 | (二)標準化、特征選擇、降為、聚類及可視化

在完成質控&#xff08;QC&#xff09;后&#xff0c;我們已經過濾掉了低質量細胞、雙細胞和低表達基因&#xff0c;獲得了較為干凈的單細胞數據集單細胞分析教程 | &#xff08;一&#xff09;Python單細胞質控全流程。接下來&#xff0c;我們將進行以下關鍵步驟&#xff1a; …

大模型 Agent(智能體)技術簡介

大模型 Agent&#xff08;智能體&#xff09;技術 是當前人工智能領域的前沿方向&#xff0c;它賦予大型語言模型&#xff08;LLM&#xff09;自主感知、規劃、決策和行動的能力&#xff0c;使其不再局限于“被動應答”&#xff0c;而是能主動完成復雜任務。簡單來說&#xff0…

OneCode 3.0架構深度剖析:工程化模塊管理與自治UI系統的設計與實現

引言 OneCode 3.0作為新一代低代碼開發平臺&#xff0c;其架構設計圍繞"工程模塊化"與"UI自主化"兩大核心目標展開。本文將從底層接口到上層應用&#xff0c;全面解析OneCode 3.0的技術架構&#xff0c;包括核心工廠類、工程管理接口、數據倉庫設計以及動態…

功耗校準數據PowerProfile測試方法建議

場景步驟版本:xxxxA1A2結果&#xff08;mA&#xff09;screen,full1.打開飛行模式&#xff0c;滅屏時間最長&#xff0c;其他的基礎功能關2.進入到日歷應用界面3.將亮度設置至最大&#xff08;4095&#xff09;&#xff0c;待電流穩定后&#xff0c;測試5分鐘&#xff0c;記錄電…

[附源碼+數據庫+畢業論文]基于Spring+MyBatis+MySQL+Maven+vue實現的供電公司安全生產考試管理系統,推薦!

摘 要 使用舊方法對安全生產考試信息進行系統化管理已經不再讓人們信賴了&#xff0c;把現在的網絡信息技術運用在安全生產考試信息的管理上面可以解決許多信息管理上面的難題&#xff0c;比如處理數據時間很長&#xff0c;數據存在錯誤不能及時糾正等問題。 這次開發的供電公…

輸入框過濾選項列表,el-checkbox-group單選

需求&#xff1a;根據輸入的文本動態過濾選項列表&#xff0c;并在下方顯示匹配到的選項。當用戶勾選匹配到的選項時&#xff0c;把該選項的值賦值給輸入框中綁定的值。當用戶取消選擇時&#xff0c;輸入框中的字段可以隨意編輯。組件&#xff1a;el-input、el-checkbox-group、…

身份認證缺陷

Authentication Bypasses審計創建AccountVerificationHelper實例&#xff0c;用于處理賬戶驗證邏輯parseSecQuestions函數的作用是從請求體中遍歷參數名&#xff0c;找到包含secQuestion的參數&#xff0c;將其值存入Map中并返回這里直接把AccountVerificationHelper整個分析一…