Android消息機(jī)制
基本原理
- 通過Handler愕宋、Looper粪薛、MessageQueue、Message蛾扇,將一個(gè)任務(wù)切換到某個(gè)指定的線程中去執(zhí)行。
- 主要是為了解決在子線程中無法訪問UI的問題魏滚。因?yàn)榧渔i會使UI控件的訪問邏輯復(fù)雜镀首,降低效率,故UI控件不是線程安全的鼠次。Android采用單線程模型來處理UI操作更哄,需要通過Handler切換UI訪問的執(zhí)行線程
- 消息處理流程:創(chuàng)建Handler,獲取當(dāng)前線程的Looper和MessageQueue腥寇;創(chuàng)建Message對象成翩,攜帶信息;Handler把Message發(fā)送到MessageQueue赦役;Looper循環(huán)獲取MessageQueue中的Message麻敌,調(diào)用Handler分發(fā)消息;Handler處理消息扩劝,執(zhí)行任務(wù)。
MessageQueue
- 單鏈表數(shù)據(jù)結(jié)構(gòu)維護(hù)消息列表职辅,存放所有Message
- 與Native層的NativeMessageQueue一起存放Message
- 先處理Native層的Message棒呛,再處理Java層的Message
主要方法
- enqueueMessage 消息入列。
- next 消息出列域携。無限循環(huán)方法簇秒,有消息就循環(huán)取出,無消息就阻塞秀鞭。
- quit 退出隊(duì)列循環(huán)趋观。
Looper
- 管理消息隊(duì)列,構(gòu)造時(shí)锋边,創(chuàng)建MessageQueue
- 非主線程Looper保存在ThreadLocal中皱坛,即Looper與線程相關(guān)
- 在子線程中手動(dòng)創(chuàng)建了Looper,用完需退出
- loop方法調(diào)用MessageQueue的next方法獲取Message豆巨,調(diào)用Handler的dispatchMessage方法處理
主要方法
- prepare 在當(dāng)前線程創(chuàng)建Looper
- loop 開啟消息循環(huán)
- prepareMainLooper 在主線程創(chuàng)建Looper
- getMainLooper 獲取主線程的Looper
- quit 直接退出隊(duì)列循環(huán)剩辟。
- quitSafely 消息處理完后,退出隊(duì)列循環(huán)
- myLooper 獲取Looper
- myQueue 獲取MessageQueue
Handler
- 發(fā)送和處理消息
- Handler構(gòu)造,可通過接口Callback創(chuàng)建Handler贩猎,但并不需要派生子類
- Handler構(gòu)造熊户,可通過Looper構(gòu)造
- 消息的處理機(jī)制:post來的消息,調(diào)用run方法吭服;用Callback創(chuàng)建的Handler實(shí)例嚷堡,調(diào)用Callback的handleMessage方法;其他則調(diào)用Handler的handleMessage方法
主要方法
- send 系列方法艇棕,發(fā)送消息
- removeMessages 移除隊(duì)列消息
- post 系列方法蝌戒,用消息的callback保存Runnable,發(fā)送消息欠肾,可定時(shí)瓶颠。
- removeCallbacks,移除隊(duì)列Runnable消息
- dispatchMessage 消息的處理分發(fā)
- handleMessage 處理消息刺桃,空方法粹淋,需重寫
- obtainMessage 系列方法,獲取消息
- getLooper 獲取Looper
Message
- 線程之間傳遞的消息瑟慈,可攜帶少量信息在不同線程間交換數(shù)據(jù)
主要方法
- 攜帶信息:兩個(gè)int桃移、Object、Bundle葛碧、Runnable
- obtain 系列方法借杰,創(chuàng)建Message
- sendToTarget 發(fā)送消息