Android中Message機制的靈活應用
正式開始介紹Android開發(fā)中Message機制應用,希望你有所收獲。
一、線程間通訊的Message機制
1、Message介紹
frameworks\base\core\java\android\Os\Message.java
Message是線程之間傳遞信息的載體,包含了對消息的描述和任意的數(shù)據(jù)對象。Message中包含了兩個額外的 int字段和一個object字段,這樣在大部分情況下,使用者就不需要再做內(nèi)存分配工作了。雖然Message的構造函數(shù)是public的,但是***是 使用Message.obtain( )或Handler.obtainMessage( )函數(shù)來獲取Message對象,因為Message的實現(xiàn)中包含了回收再利用的機制,可以提供效率。
2、MessageQueue介紹
frameworks\base\core\java\android\Os\MessageQueue.java
MessageQueue用來容納Message隊列的,其中的Message是由Looper來分發(fā)的,Message不能直接添加到MessageQueue中,而是要通過與Looper關聯(lián)的Handler去添加。
3、Looper
frameworks\base\core\java\android\Os\Looper.java
Looper是線程用來運行消息循環(huán)的。線程本身是沒有消息循環(huán)的,需要在線程中調(diào)用perpare函數(shù),然后調(diào)用loop去處理消息。在Android中,系統(tǒng)在啟動主線程的時候會自動為之建立一個Looper。
建立本線程的Looper:
public static final void prepare()
運行本線程的Looper:
public static final void loop()
獲取本線程的Looper:
public static final Looper myLooper()
獲取主線程的Looper:
public synchronized static final Looper getMainLooper()
4、Handler
frameworks\base\core\java\android\Os\Handler.java
Handler是用來發(fā)送和處理與線程相關聯(lián)的Message和Runnable對象的。每個Handler都與一個單獨的線程以及線程消息隊列相 關聯(lián)的。當你創(chuàng)建Handler時,Handler就與線程以及線程消息隊列綁定了,從那以后,Handler就可以將 Message和Runnable發(fā)送給對應的消息隊列,并且能夠處理從消息隊列中出來的消息。
Handler提供了用戶需要調(diào)用的大部分接口
A、創(chuàng)建Handler:
創(chuàng)建與本地線程相關聯(lián)的Handler:
public Handler()
public Handler(Callback callback)
創(chuàng)建與指定線程相關聯(lián)的Handler:
public Handler(Looper looper)
public Handler(Looper looper, Callback callback)
B、創(chuàng)建消息
- public final Message obtainMessage()
- public final Message obtainMessage(int what)
- public final Message obtainMessage(int what, Object obj)
- public final Message obtainMessage(int what, int arg1, int arg2)
- public final Message obtainMessage(int what, int arg1, int arg2, Object obj)
C、刪除消息
刪除在消息隊列中未處理的消息
- public final void removeMessages(int what)
- public final void removeMessages(int what, Object object)
D、發(fā)送消息
- public final boolean sendMessage(Message msg)
- public final boolean sendMessageDelayed(Message msg, long delayMillis)
- public final boolean post(Runnable r)
- public final boolean postDelayed(Runnable r, long delayMillis)
E、處理消息
在Looper的loop函數(shù)中循環(huán)取出MessageQueue的接收消息隊列中的消息,然后調(diào)用Hander的dispatchMessage函數(shù)對消息進行處理,至于如何處理(相應消息)則由用戶指 定(三個方法,優(yōu)先級從高到低:Message里面的Callback,一個實現(xiàn)了Runnable接口的對象,其中run函數(shù)做處理工 作;Handler里面的mCallback指向的一個實現(xiàn)了Callback接口的對象,里面的handleMessage進行處理;處理消息 Handler對象對應的類繼承并實現(xiàn)了其中handleMessage函數(shù),通過這個實現(xiàn)的handleMessage函數(shù)處理消息)。
- public void dispatchMessage(Message msg) {
- if (msg.callback != null) {
- handleCallback(msg);
- } else {
- if (mCallback != null) {
- if (mCallback.handleMessage(msg)) {
- return;
- }
- }
- handleMessage(msg);
- }
- }
二、Message機制的用途
Message機制有兩種用途:
定時執(zhí)行:延遲到指定時間執(zhí)行消息調(diào)度
線程通訊:將某些操作在其他線程中排隊執(zhí)行
1、定時執(zhí)行
通過本線程的Handler將消息延遲到指定時間執(zhí)行,相當于定時器的作用
- public final boolean sendMessageDelayed(Message msg, long delayMillis)
- public final boolean postDelayed(Runnable r, long delayMillis)
還可以在指定時間到期之前,通過removeMessages取消執(zhí)行
2、線程通訊
Android的UI是單線程的,Android希望UI線程能夠給予User快速的反應,如果UI線程花費太多的時間做幕后的事情,吵過5秒 鐘,Android就會給出錯誤提示。因此為了避免拖住UI,一下較費時的工作應該交給獨立的線程去執(zhí)行。但是如果幕后的線程來執(zhí)行UI對 象,Android又會發(fā)出錯誤信息,所以UI線程與幕后線程需要進行通訊。UI線程將工作分發(fā)給幕后線程,幕后線程執(zhí)行后將相應的狀態(tài)返回給UI線程, 讓UI線程對UI做成相應的更新。
總結:所謂的消息機制其實很簡單,實現(xiàn)這種機制需要只需要四步:
1、實例化Looper(因為實例化Handler時需要一個looper);
2、實例化Handler,這里需要覆蓋handleMessage方法,處理收到的消息;
3、 實例化Message對象,調(diào)用已經(jīng)實例化好的handler對象的obtainMessage方法,把數(shù)據(jù)傳給obtainMessage方 法,obtainMessage方法就會實例化一個Message對象。(這里也可以發(fā)送實現(xiàn)Runnable接口的對象);
4、調(diào)用Handler的sendMessage方法把實例化好的Message對象發(fā)送出去。對每個線程過程都是一樣的,只要按照上面的四個步驟來就可以發(fā)送和接收消息了。
通過全文的閱讀相信你已經(jīng)對Message機制應用有了一定的理解,希望今后多多實踐練習,一定會熟練掌握。