版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
Handler消息傳遞機(jī)制2023/9/28072023/9/28消息處理機(jī)制消息處理對(duì)象目錄CONTENT12異步加載圖像示例3參考教材:《Android應(yīng)用開(kāi)發(fā)項(xiàng)目化教程》消息處理機(jī)制思路Android通過(guò)Looper、Handler來(lái)實(shí)現(xiàn)消息循環(huán)機(jī)制。Android的消息循環(huán)是針對(duì)線程的,每個(gè)線程都可以有自己的消息隊(duì)列和消息循環(huán)。1消息處理機(jī)制核心對(duì)象Message消息,理解為線程間通訊的數(shù)據(jù)單元。MessageQueue消息隊(duì)列,用來(lái)存放通過(guò)Handler發(fā)布的消息,按照先進(jìn)先出執(zhí)行。HandlerHandler是Message的主要處理者,負(fù)責(zé)將Message添加到消息隊(duì)列以及對(duì)消息隊(duì)列中的Message進(jìn)行處理。1Looper循環(huán)器,扮演MessageQueue和Handler之間橋梁的角色,循環(huán)取出MessageQueue里面的Message,并交付給相應(yīng)的Handler進(jìn)行處理。線程每一個(gè)線程里可含有一個(gè)Looper對(duì)象以及一個(gè)MessageQueue數(shù)據(jù)結(jié)構(gòu)。在應(yīng)用程序里,可以定義Handler的子類別來(lái)接收Looper所送出的消息。消息處理機(jī)制一般處理流程包裝Message對(duì)象(指定Handler、回調(diào)函數(shù)和攜帶數(shù)據(jù)等);通過(guò)Handler的sendMessage()等類似方法將Message發(fā)送出去;在Handler的處理方法里面將Message添加到Handler綁定的Looper的MessageQueue;Looper的loop()方法通過(guò)循環(huán)不斷從MessageQueue里面提取Message進(jìn)行處理,并移除處理完畢的Message;通過(guò)調(diào)用Message綁定的Handler對(duì)象的dispatchMessage()方法完成對(duì)消息的處理。1消息處理對(duì)象Looper被設(shè)計(jì)用來(lái)使一個(gè)普通線程變成Looper線程。Looper線程就是循環(huán)工作的線程。在程序開(kāi)發(fā)中(尤其是GUI開(kāi)發(fā)中),我們經(jīng)常會(huì)需要一個(gè)線程不斷循環(huán),一旦有新任務(wù)則執(zhí)行,執(zhí)行完繼續(xù)等待下一個(gè)任務(wù),這就是Looper線程。每個(gè)線程有且最多只能有一個(gè)Looper對(duì)象,它是一個(gè)ThreadLocalLooper內(nèi)部有一個(gè)消息隊(duì)列MessageQueue,消息隊(duì)列在Looper的構(gòu)造函數(shù)中被創(chuàng)建并且作為成員變量被保存,也就是說(shuō)MessageQueue相對(duì)于線程也是唯一的。loop()方法調(diào)用后線程開(kāi)始不斷從隊(duì)列中取出消息執(zhí)行Looper使一個(gè)線程變成Looper線程2消息處理對(duì)象Looper創(chuàng)建Looper線程Android應(yīng)用在啟動(dòng)的時(shí)候會(huì)默認(rèn)會(huì)為主線程創(chuàng)建一個(gè)Looper實(shí)例,并借助相關(guān)的Handler和Looper里面的MessageQueue完成對(duì)Activities、Services、BroadcaseReceivers等的管理。2消息處理對(duì)象Looper創(chuàng)建Looper線程而在子線程中,Looper需要通過(guò)顯式調(diào)用Looper.Prepare()方法進(jìn)行創(chuàng)建。Prepare方法通過(guò)ThreadLocal來(lái)保證Looper在線程內(nèi)的唯一性,如果Looper在線程內(nèi)已經(jīng)被創(chuàng)建并且嘗試再度創(chuàng)建"OnlyoneLoopermaybecreatedperthread"異常將被拋出。2消息處理對(duì)象Looper核心方法Looper.prepare()Looper.loop()不斷從自己的MQ中取出隊(duì)頭的消息執(zhí)行Looper.myLooper()得到當(dāng)前線程Looper對(duì)象Looper.getThread()得到Looper對(duì)象所屬線程Looper.quit()結(jié)束Looper循環(huán)2消息處理對(duì)象Handler被設(shè)計(jì)用來(lái)向MessageQueue中添加消息和處理消息。Handler只處理由自己發(fā)出的消息,即通知MessageQueue要執(zhí)行一個(gè)任務(wù)(sendMessage()),并在loop()到自己的時(shí)候執(zhí)行該任務(wù)(handleMessage()),整個(gè)過(guò)程是異步的。每個(gè)Handler都會(huì)與唯一的一個(gè)線程以及該線程的消息隊(duì)列關(guān)聯(lián)。當(dāng)創(chuàng)建一個(gè)新的Handler時(shí),默認(rèn)情況下,它將關(guān)聯(lián)到創(chuàng)建它的這個(gè)線程和該線程的消息隊(duì)列。因此,如果通過(guò)Handler發(fā)布消息的話,消息將只會(huì)發(fā)送到與它關(guān)聯(lián)的這個(gè)消息隊(duì)列,當(dāng)然也只能處理該消息隊(duì)列中的消息。2消息處理對(duì)象Handler設(shè)計(jì)Handler2提示:一個(gè)線程可以有多個(gè)Handler,但是只能有一個(gè)Looper!消息處理對(duì)象Handler設(shè)計(jì)HandlerHandler在創(chuàng)建的時(shí)候可以指定Looper,這樣通過(guò)Handler的sendMessage()方法發(fā)送出去的消息就會(huì)添加到指定Looper里面的MessageQueue里面去。在不指定Looper的情況下,Handler綁定的是創(chuàng)建它的線程的Looper。如果這個(gè)線程的Looper不存在,程序?qū)伋?Can'tcreatehandlerinsidethreadthathasnotcalledLooper.prepare()"。2消息處理對(duì)象HandlerHandler發(fā)送消息post(Runnable)postAtTime(Runnable,long)postDelayed(Runnable,long)sendEmptyMessage(int)sendMessage(Message)sendMessageAtTime(Message,long)sendMessageDelayed(Message,long)2Handler可以在任意線程發(fā)送消息,這些消息會(huì)被添加到關(guān)聯(lián)的MQ上。消息處理對(duì)象HandlerHandler發(fā)送消息sendMessage()或post()發(fā)出的消息都會(huì)插在消息隊(duì)列隊(duì)尾并按先進(jìn)先出執(zhí)行。區(qū)別:通過(guò)sendMessage()發(fā)送的是一個(gè)Message對(duì)象,會(huì)被Handler的handleMessage()方法處理通過(guò)post方法發(fā)送的是一個(gè)Runnable對(duì)象,會(huì)被封裝成Message對(duì)象執(zhí)行。2消息處理對(duì)象HandlerHandler發(fā)送消息message.target為該Handler對(duì)象,這確保了Looper執(zhí)行到該Message時(shí)能找到處理它的Handler,即loop()方法中的代碼:msg.target.dispatchMessage(msg);。post發(fā)出的Message,其回調(diào)為Runnable對(duì)象。消息的處理是通過(guò)核心方法dispatchMessage(Messagemsg)與鉤子方法handleMessage(Messagemsg)完成的。2消息處理對(duì)象HandlerHandler處理消息核心方法dispatchMessage(Messagemsg)handleMessage(Messagemsg)2Handler是在它關(guān)聯(lián)的Looper線程中處理消息的。消息處理對(duì)象HandlerHandler處理消息dispatchMessage()方法機(jī)制Message里面的Callback,一個(gè)實(shí)現(xiàn)了Runnable接口的對(duì)象,其中run函數(shù)做處理工作Handler里面mCallback指向的一個(gè)實(shí)現(xiàn)了Callback接口的對(duì)象,由其handleMessage進(jìn)行處理
處理消息Handler對(duì)象對(duì)應(yīng)的類繼承并實(shí)現(xiàn)了其中handleMessage函數(shù),通過(guò)這個(gè)實(shí)現(xiàn)的handleMessage函數(shù)處理消息。2消息處理對(duì)象HandlerHandler更新UI流程在Activity中創(chuàng)建Handler并將其引用傳遞給工作線程,工作線程執(zhí)行完任務(wù)后使用Handler發(fā)送消息通知Activity更新UI。2消息處理對(duì)象Message和MessageQueueMessageMessage是一個(gè)Parcelable對(duì)象。Message是線程之間傳遞信息的載體,包含了對(duì)消息的描述和任意的數(shù)據(jù)對(duì)象。Message中包含了兩個(gè)額外的int字段(Message.arg1和Message.arg2)和一個(gè)Object字段,并通過(guò)Message.what來(lái)標(biāo)識(shí)信息,以便用不同方式處理Message。雖然Message的構(gòu)造方法是public的,但是最好是使用Message.obtain()或Handler.obtainMessage()方法來(lái)獲取Message對(duì)象,因?yàn)镸essage的實(shí)現(xiàn)中包含了回收再利用的機(jī)制,可以提高效率。2消息處理對(duì)象Message和MessageQueueMessageQueueMessageQueue是用來(lái)容納Message隊(duì)列的,其中的Message是由Looper來(lái)分發(fā)的。Message不能直接添加到MessageQueue中,而是要通過(guò)與Looper關(guān)聯(lián)的Handler去添加。消息隊(duì)列通常附屬于某一個(gè)創(chuàng)建它的線程,可以通過(guò)Looper.myQueue()得到當(dāng)前線程的消息隊(duì)列。如果沒(méi)有消息隊(duì)列對(duì)象則會(huì)拋出空指針異常。Android在第一次啟動(dòng)程序時(shí)會(huì)默認(rèn)會(huì)為UIThread創(chuàng)建一個(gè)關(guān)聯(lián)的消息隊(duì)列,用來(lái)管理程序的一些上層組件??梢栽谧约旱淖泳€程中創(chuàng)建Handler與UIThread通訊。也就是說(shuō)程序一啟動(dòng)UI線程也就是主線程就會(huì)有一個(gè)消息隊(duì)列,而如果自己另外開(kāi)啟的一個(gè)子線程就不會(huì)有MessageQueue對(duì)象。2異步加載圖像示例在UI線程中定義一個(gè)Handler在PhotoManager工具類的構(gòu)造方法里定義Handler稍后在這個(gè)Handler里重寫handleMessage()方法。當(dāng)這個(gè)Handler接收到由另外一個(gè)線程管理的Handler發(fā)送過(guò)來(lái)的新消息時(shí),Android系統(tǒng)會(huì)自動(dòng)調(diào)用這個(gè)方法,而所有線程對(duì)應(yīng)的Handler都會(huì)收到相同信息。3異步加載圖像示例把數(shù)據(jù)從一個(gè)任務(wù)中轉(zhuǎn)移到UI線程在任務(wù)對(duì)象中存儲(chǔ)數(shù)據(jù)定義一個(gè)Runnable,它運(yùn)行在一個(gè)編碼了一個(gè)Bitmap且存儲(chǔ)這個(gè)Bitmap到父類PhotoTask對(duì)象里的后臺(tái)線程。3異步加載圖像示例把數(shù)據(jù)從一個(gè)任務(wù)中轉(zhuǎn)移到UI線程在后臺(tái)編碼PhotoTask是下一個(gè)層次更高的對(duì)象,它包含將要展示數(shù)據(jù)的編碼數(shù)據(jù)和View對(duì)象的引用。它會(huì)收到一個(gè)來(lái)自PhotoDecodeRunnable的狀態(tài)碼,并把這個(gè)狀態(tài)碼單獨(dú)傳遞到一個(gè)包含線程池和Handler實(shí)例的對(duì)象。3異步加載圖像示例轉(zhuǎn)移數(shù)據(jù)到UI處理狀態(tài)
PhotoManager對(duì)象收到了一個(gè)狀態(tài)碼和一個(gè)PhotoTask對(duì)象的handler。因?yàn)闋顟B(tài)碼是TASK_COMPLETE,所以創(chuàng)建一
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五年度倉(cāng)儲(chǔ)物流中心房屋出租及倉(cāng)儲(chǔ)管理合同
- 四川省眉山市東坡區(qū)2024-2025學(xué)年高二上學(xué)期期末考試歷史試題(含答案)
- 福建省部分地市2025屆高中畢業(yè)班第一次質(zhì)量檢測(cè) 生物試卷(含答案)
- 2024版婚前合同:情感與財(cái)產(chǎn)的明確界定版B版
- 2024版夫妻離婚及子女撫養(yǎng)協(xié)議書(shū)
- 2024石材加工廠技術(shù)創(chuàng)新與研發(fā)團(tuán)隊(duì)建設(shè)的合同范本
- 2024項(xiàng)目合作開(kāi)發(fā)與技術(shù)保密協(xié)議3篇
- 福建省南平市建陽(yáng)縣徐市中學(xué)高三英語(yǔ)期末試卷含解析
- 2025年度建筑工地安全生產(chǎn)應(yīng)急物資儲(chǔ)備及供應(yīng)合同3篇
- 2024生豬銷售與養(yǎng)殖場(chǎng)環(huán)保設(shè)施建設(shè)合同3篇
- 班組長(zhǎng)薪酬體系設(shè)計(jì)方案
- 持續(xù)改進(jìn)管理程序
- 網(wǎng)絡(luò)安全設(shè)備巡檢報(bào)告
- 校園廣播系統(tǒng)施工安裝方案
- 石群邱關(guān)源電路課件(第8至16單元)白底
- 暫緩執(zhí)行拘留申請(qǐng)書(shū)
- 蘇教版中外戲劇名著選讀《玩偶之家》評(píng)課稿
- 經(jīng)方在消化系統(tǒng)疾病中的運(yùn)用
- 【機(jī)械手】-機(jī)械手編程指令
- 格庫(kù)鐵路S標(biāo)項(xiàng)目部二工區(qū)混凝土拌和站管理辦法
- 《靈飛經(jīng)》原帖對(duì)照鋼筆字帖
評(píng)論
0/150
提交評(píng)論