《Android移動應用開發(fā)》應用程序的消息處理機制_第1頁
《Android移動應用開發(fā)》應用程序的消息處理機制_第2頁
《Android移動應用開發(fā)》應用程序的消息處理機制_第3頁
《Android移動應用開發(fā)》應用程序的消息處理機制_第4頁
《Android移動應用開發(fā)》應用程序的消息處理機制_第5頁
已閱讀5頁,還剩20頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

Handler消息傳遞機制2023/9/28072023/9/28消息處理機制消息處理對象目錄CONTENT12異步加載圖像示例3參考教材:《Android應用開發(fā)項目化教程》消息處理機制思路Android通過Looper、Handler來實現(xiàn)消息循環(huán)機制。Android的消息循環(huán)是針對線程的,每個線程都可以有自己的消息隊列和消息循環(huán)。1消息處理機制核心對象Message消息,理解為線程間通訊的數(shù)據(jù)單元。MessageQueue消息隊列,用來存放通過Handler發(fā)布的消息,按照先進先出執(zhí)行。HandlerHandler是Message的主要處理者,負責將Message添加到消息隊列以及對消息隊列中的Message進行處理。1Looper循環(huán)器,扮演MessageQueue和Handler之間橋梁的角色,循環(huán)取出MessageQueue里面的Message,并交付給相應的Handler進行處理。線程每一個線程里可含有一個Looper對象以及一個MessageQueue數(shù)據(jù)結構。在應用程序里,可以定義Handler的子類別來接收Looper所送出的消息。消息處理機制一般處理流程包裝Message對象(指定Handler、回調函數(shù)和攜帶數(shù)據(jù)等);通過Handler的sendMessage()等類似方法將Message發(fā)送出去;在Handler的處理方法里面將Message添加到Handler綁定的Looper的MessageQueue;Looper的loop()方法通過循環(huán)不斷從MessageQueue里面提取Message進行處理,并移除處理完畢的Message;通過調用Message綁定的Handler對象的dispatchMessage()方法完成對消息的處理。1消息處理對象Looper被設計用來使一個普通線程變成Looper線程。Looper線程就是循環(huán)工作的線程。在程序開發(fā)中(尤其是GUI開發(fā)中),我們經(jīng)常會需要一個線程不斷循環(huán),一旦有新任務則執(zhí)行,執(zhí)行完繼續(xù)等待下一個任務,這就是Looper線程。每個線程有且最多只能有一個Looper對象,它是一個ThreadLocalLooper內(nèi)部有一個消息隊列MessageQueue,消息隊列在Looper的構造函數(shù)中被創(chuàng)建并且作為成員變量被保存,也就是說MessageQueue相對于線程也是唯一的。loop()方法調用后線程開始不斷從隊列中取出消息執(zhí)行Looper使一個線程變成Looper線程2消息處理對象Looper創(chuàng)建Looper線程Android應用在啟動的時候會默認會為主線程創(chuàng)建一個Looper實例,并借助相關的Handler和Looper里面的MessageQueue完成對Activities、Services、BroadcaseReceivers等的管理。2消息處理對象Looper創(chuàng)建Looper線程而在子線程中,Looper需要通過顯式調用Looper.Prepare()方法進行創(chuàng)建。Prepare方法通過ThreadLocal來保證Looper在線程內(nèi)的唯一性,如果Looper在線程內(nèi)已經(jīng)被創(chuàng)建并且嘗試再度創(chuàng)建"OnlyoneLoopermaybecreatedperthread"異常將被拋出。2消息處理對象Looper核心方法Looper.prepare()Looper.loop()不斷從自己的MQ中取出隊頭的消息執(zhí)行Looper.myLooper()得到當前線程Looper對象Looper.getThread()得到Looper對象所屬線程Looper.quit()結束Looper循環(huán)2消息處理對象Handler被設計用來向MessageQueue中添加消息和處理消息。Handler只處理由自己發(fā)出的消息,即通知MessageQueue要執(zhí)行一個任務(sendMessage()),并在loop()到自己的時候執(zhí)行該任務(handleMessage()),整個過程是異步的。每個Handler都會與唯一的一個線程以及該線程的消息隊列關聯(lián)。當創(chuàng)建一個新的Handler時,默認情況下,它將關聯(lián)到創(chuàng)建它的這個線程和該線程的消息隊列。因此,如果通過Handler發(fā)布消息的話,消息將只會發(fā)送到與它關聯(lián)的這個消息隊列,當然也只能處理該消息隊列中的消息。2消息處理對象Handler設計Handler2提示:一個線程可以有多個Handler,但是只能有一個Looper!消息處理對象Handler設計HandlerHandler在創(chuàng)建的時候可以指定Looper,這樣通過Handler的sendMessage()方法發(fā)送出去的消息就會添加到指定Looper里面的MessageQueue里面去。在不指定Looper的情況下,Handler綁定的是創(chuàng)建它的線程的Looper。如果這個線程的Looper不存在,程序將拋出"Can'tcreatehandlerinsidethreadthathasnotcalledLooper.prepare()"。2消息處理對象HandlerHandler發(fā)送消息post(Runnable)postAtTime(Runnable,long)postDelayed(Runnable,long)sendEmptyMessage(int)sendMessage(Message)sendMessageAtTime(Message,long)sendMessageDelayed(Message,long)2Handler可以在任意線程發(fā)送消息,這些消息會被添加到關聯(lián)的MQ上。消息處理對象HandlerHandler發(fā)送消息sendMessage()或post()發(fā)出的消息都會插在消息隊列隊尾并按先進先出執(zhí)行。區(qū)別:通過sendMessage()發(fā)送的是一個Message對象,會被Handler的handleMessage()方法處理通過post方法發(fā)送的是一個Runnable對象,會被封裝成Message對象執(zhí)行。2消息處理對象HandlerHandler發(fā)送消息message.target為該Handler對象,這確保了Looper執(zhí)行到該Message時能找到處理它的Handler,即loop()方法中的代碼:msg.target.dispatchMessage(msg);。post發(fā)出的Message,其回調為Runnable對象。消息的處理是通過核心方法dispatchMessage(Messagemsg)與鉤子方法handleMessage(Messagemsg)完成的。2消息處理對象HandlerHandler處理消息核心方法dispatchMessage(Messagemsg)handleMessage(Messagemsg)2Handler是在它關聯(lián)的Looper線程中處理消息的。消息處理對象HandlerHandler處理消息dispatchMessage()方法機制Message里面的Callback,一個實現(xiàn)了Runnable接口的對象,其中run函數(shù)做處理工作Handler里面mCallback指向的一個實現(xiàn)了Callback接口的對象,由其handleMessage進行處理

處理消息Handler對象對應的類繼承并實現(xiàn)了其中handleMessage函數(shù),通過這個實現(xiàn)的handleMessage函數(shù)處理消息。2消息處理對象HandlerHandler更新UI流程在Activity中創(chuàng)建Handler并將其引用傳遞給工作線程,工作線程執(zhí)行完任務后使用Handler發(fā)送消息通知Activity更新UI。2消息處理對象Message和MessageQueueMessageMessage是一個Parcelable對象。Message是線程之間傳遞信息的載體,包含了對消息的描述和任意的數(shù)據(jù)對象。Message中包含了兩個額外的int字段(Message.arg1和Message.arg2)和一個Object字段,并通過Message.what來標識信息,以便用不同方式處理Message。雖然Message的構造方法是public的,但是最好是使用Message.obtain()或Handler.obtainMessage()方法來獲取Message對象,因為Message的實現(xiàn)中包含了回收再利用的機制,可以提高效率。2消息處理對象Message和MessageQueueMessageQueueMessageQueue是用來容納Message隊列的,其中的Message是由Looper來分發(fā)的。Message不能直接添加到MessageQueue中,而是要通過與Looper關聯(lián)的Handler去添加。消息隊列通常附屬于某一個創(chuàng)建它的線程,可以通過Looper.myQueue()得到當前線程的消息隊列。如果沒有消息隊列對象則會拋出空指針異常。Android在第一次啟動程序時會默認會為UIThread創(chuàng)建一個關聯(lián)的消息隊列,用來管理程序的一些上層組件??梢栽谧约旱淖泳€程中創(chuàng)建Handler與UIThread通訊。也就是說程序一啟動UI線程也就是主線程就會有一個消息隊列,而如果自己另外開啟的一個子線程就不會有MessageQueue對象。2異步加載圖像示例在UI線程中定義一個Handler在PhotoManager工具類的構造方法里定義Handler稍后在這個Handler里重寫handleMessage()方法。當這個Handler接收到由另外一個線程管理的Handler發(fā)送過來的新消息時,Android系統(tǒng)會自動調用這個方法,而所有線程對應的Handler都會收到相同信息。3異步加載圖像示例把數(shù)據(jù)從一個任務中轉移到UI線程在任務對象中存儲數(shù)據(jù)定義一個Runnable,它運行在一個編碼了一個Bitmap且存儲這個Bitmap到父類PhotoTask對象里的后臺線程。3異步加載圖像示例把數(shù)據(jù)從一個任務中轉移到UI線程在后臺編碼PhotoTask是下一個層次更高的對象,它包含將要展示數(shù)據(jù)的編碼數(shù)據(jù)和View對象的引用。它會收到一個來自PhotoDecodeRunnable的狀態(tài)碼,并把這個狀態(tài)碼單獨傳遞到一個包含線程池和Handler實例的對象。3異步加載圖像示例轉移數(shù)據(jù)到UI處理狀態(tài)

PhotoManager對象收到了一個狀態(tài)碼和一個PhotoTask對象的handler。因為狀態(tài)碼是TASK_COMPLETE,所以創(chuàng)建一

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論