android异步线程利用Handler将消息发送至UI线程
android UI線程安全
首先對(duì)于android而言,UI線程就是我們的主線程,在Android應(yīng)用啟動(dòng)時(shí),會(huì)自動(dòng)創(chuàng)建一個(gè)線程,主線程負(fù)責(zé)UI的展示、UI事件消息的派發(fā)處理等等,因此主線程也叫做UI線程。
- 線程安全的定義
線程安全是多線程編程時(shí)的計(jì)算機(jī)程序代碼中的一個(gè)概念。在擁有共享數(shù)據(jù)的多條線程并行執(zhí)行的程序中,線程安全的代碼會(huì)通過(guò)同步機(jī)制保證各個(gè)線程都可以正常且正確的執(zhí)行,不會(huì)出現(xiàn)數(shù)據(jù)污染等意外情況。
如果你的代碼所在的進(jìn)程中有多個(gè)線程在同時(shí)運(yùn)行,而這些線程可能會(huì)同時(shí)運(yùn)行這段代碼。如果每次運(yùn)行結(jié)果和單線程運(yùn)行的結(jié)果是一樣的,而且其他的變量的值也和預(yù)期的是一樣的,就是線程安全的,或者說(shuō):一個(gè)類(lèi)或者程序所提供的接口對(duì)于線程來(lái)說(shuō)是原子操作或者多個(gè)線程之間的切換不會(huì)導(dǎo)致該接口的執(zhí)行結(jié)果存在二義性,也就是說(shuō)我們不用考慮同步的問(wèn)題 。
- 為什么說(shuō)Android UI不是線程安全的?
UI線程才能與Android UI工具包中的組件進(jìn)行交互,在開(kāi)發(fā)Android應(yīng)用時(shí)必須遵守單線程模型的原則:
android UI 中提供invalidate()來(lái)更新界面,而invalidate()方法是線程不安全。
Android提供了Invalidate方法實(shí)現(xiàn)界面刷新,但是Invalidate不能直接在非UI主線程中調(diào)用,因?yàn)樗沁`背了單線程模型:Android UI操作并不是線程安全的,并且這些操作必須在UI線程中調(diào)用。例如:在非UI線程中調(diào)用invalidate會(huì)導(dǎo)致線程不安全,也就是說(shuō)可能在非UI線程中刷新界面的時(shí)候,UI線程(或者其他非UI線程)也在刷新界面,這樣就導(dǎo)致多個(gè)界面刷新的操作不能同步,導(dǎo)致線程不安全。
Handler類(lèi)
Handler主要用于異步消息的處理:當(dāng)發(fā)出一個(gè)消息之后,首先進(jìn)入一個(gè)消息隊(duì)列,發(fā)送消息的函數(shù)即刻返回,而另外一個(gè)部分在消息隊(duì)列中逐一將消息取出,然后對(duì)消息進(jìn)行處理,也就是發(fā)送消息和接收消息不是同步的處理。 這種機(jī)制通常用來(lái)處理相對(duì)耗時(shí)比較長(zhǎng)的操作。
傳遞Message。用于接受子線程發(fā)送的數(shù)據(jù), 并用此數(shù)據(jù)配合主線程更新UI。
在Android中,對(duì)于UI的操作通常需要放在主線程中進(jìn)行操作。如果在子線程中有關(guān)于UI的操作,那么就需要把數(shù)據(jù)消息作為一個(gè)Message對(duì)象發(fā)送到消息隊(duì)列中,然后,由Handler中的handlerMessage方法處理傳過(guò)來(lái)的數(shù)據(jù)信息,并操作UI。當(dāng)然,Handler對(duì)象是在主線程中初始化的,因?yàn)樗枰壎ㄔ谥骶€程的消息隊(duì)列中。
類(lèi)sendMessage(Message msg)方法實(shí)現(xiàn)發(fā)送消息的操作。 在初始化Handler對(duì)象時(shí)重寫(xiě)的handleMessage方法來(lái)接收Message并進(jìn)行相關(guān)操作。
- Message
Message是Handler接收與處理的消息對(duì)象
其中msg.what主要用于區(qū)分handler接受到的message實(shí)例。根據(jù)此區(qū)分,Handler可以對(duì)消息進(jìn)行不同的處理操作。
msg.setData(),可以將數(shù)據(jù)存入msg。
利用handler.sendMessage(msg);將消息發(fā)送給Handler
通過(guò)Handler類(lèi)將子線程中更新UI的消息發(fā)送至UI線程更新UI
- 子線程中
因?yàn)樵贏ndroid段進(jìn)行異步網(wǎng)絡(luò)請(qǐng)求獲取數(shù)據(jù)的時(shí)候,成功獲取得到數(shù)據(jù)是在子線程中的,因?yàn)閁I更新是需要在UI線程(主線程)中進(jìn)行的。所以需要發(fā)送一個(gè)Message給Handler,在主線程中接收消息并處理。
- 主線程中
主線程接收并處理子線程中發(fā)送的Message
參考資料
- 定義部分摘自:https://www.jianshu.com/p/8e65b2d66162
總結(jié)
以上是生活随笔為你收集整理的android异步线程利用Handler将消息发送至UI线程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Spring Boot项目无法找到get
- 下一篇: 强网杯2020-dice2crybaby