Android中的訊息機制

2021-07-22 12:58:31 字數 3913 閱讀 1795

今天**android中的訊息機制,主要包括訊息的傳送、接收以及與執行緒之間的關係。完成這一過程主要需要以下三個類的協作:looper,handler,messagequeue。先給出乙個總體圖:

每乙個looper都會和乙個執行緒繫結。要建立乙個新的looper並將它同當前的執行緒繫結起來,你必須要呼叫looper.prepare()方法。這些looper都被儲存在looper類裡面的靜態threadlocal變數裡面。你可以通過呼叫looper.mylooper()方法來獲取與當前執行緒相關聯的looper。

class looper  

sthreadlocal.set(new looper());

}

//...

//訊息迴圈

public static final void loop()

if (msg != null)

if (me.mlogging!= null) me.mlogging.println(

">>>>> dispatching to " + msg.target + " "

+ msg.callback + ": " + msg.what

);

msg.target.dispatchmessage(msg);

if (me.mlogging!= null) me.mlogging.println(

"<<<<< finished to " + msg.target + " "

+ msg.callback);

msg.recycle();

} }

}

//返回和執行緒相關的looper

public static final looper mylooper()

}

handler

handler配合looper完成訊息的傳送及分發處理。即:

1、從任意執行緒傳送訊息給looper的訊息佇列;2、處理相關聯的looper發過來的訊息。

乙個looper可以關聯多個handler。looper會把message傳送到message.target(它就是乙個handler,通過msg.target = this; 設定)。例如,在activity中新建的handler成員變數,都是關聯到主線程的looper中的。

handler的無參建構函式會獲取與當前執行緒相關聯的looper。你要確認當前執行緒是否是你的handler想要關聯的執行緒。

handler handler = new handler();這樣做會更明確地關聯到ui執行緒:

handler handler = new handler(looper.getmainlooper());

看看handler的主要原始碼:

class handler  

//直接把looper的queue和自己的queue設定 同乙個,這樣的話,通過handler的封裝機制加訊息的話,就相當於直接加到了looper的訊息佇列中去了

mqueue = mlooper.mqueue;

mcallback = null;

}//還有好幾種建構函式,乙個是帶callback的,乙個是帶looper的

//由外部設定looper

public handler(looper looper)

// 帶callback的,乙個handler可以設定乙個callback。如果有callback的話,

//凡是發到通過這個handler傳送的訊息,都有callback處理,相當於乙個總的集中處理

//待會看dispatchmessage的時候再分析

public handler(looper looper, callback callback)

//通過handler傳送訊息

//呼叫了內部的乙個sendmessagedelayed

public final boolean sendmessage(message msg)

//ft,又封裝了一層,這回是呼叫sendmessageattime了

//因為延時時間是基於當前呼叫時間的,所以需要獲得絕對時間傳遞給sendmessageattime

public final boolean sendmessagedelayed(message msg, long delaymillis)

return sendmessageattime(msg, systemclock.uptimemillis() + delaymillis);

}

public boolean sendmessageattime(message msg, long uptimemillis)

else

return sent;

} //還記得looper中的那個訊息迴圈處理嗎

//從訊息佇列中得到乙個訊息後,會呼叫它的target的dispatchmesage函式

//message的target已經設定為handler了,所以

//最後會轉到handler的msg處理上來

//這裡有個處理流程的問題

public void dispatchmessage(message msg) else

} //否則交給派生處理,基類預設處理是什麼都不幹

handlemessage(msg);

} }

}

要建立handler,首先要有looper,才能建立訊息系統。

ui更新

android的訊息機制就很好地解決了這個問題:乙個message經由handler的傳送,messagequeue的入隊,looper的抽取分發,又再一次地回到handler的處理。繞過的這一圈,正好幫助我們將同步操作變成了非同步操作。

我們知道,要正常地更新ui,主要有以下4種方式可以從其它執行緒訪問ui執行緒:

1、activity.runonuithread(runnable)2、view.post(runnable)3、view.postdelayed(runnable, long)4、handler

重點說一下的是view.post(runnable)方法。在post(runnable action)方法裡,view獲得當前執行緒(即ui執行緒)的handler,然後將action物件post到handler裡。在handler裡,它將傳遞過來的action物件包裝成乙個message(message的callback為action),然後將其投入ui執行緒的訊息迴圈中。在handler再次處理該message時,有一條分支(dispatchmessage中)就是為它所設,直接呼叫runnable的run方法。而此時,已經路由到ui執行緒裡,因此,我們可以毫無顧慮的來更新ui。

view.post處理訊息的分支(第乙個if分支):

public void dispatchmessage(message msg)  else   

} //否則交給派生處理,基類預設處理是什麼都不幹

handlemessage(msg);

} }

主線程

public class activitythread 

looper.loop();

}}

所以,在activity中新建的handler成員變數,或者在新建handler時傳遞給建構函式的引數是looper.getmainlooper()的handler,都是在主線程的訊息迴圈佇列中的。

參考:1、

2、3、

4、

Android中訊息機制詳解

android 執行緒問題主要概念 1 messagequeue 是一種資料結構,見名知義,就是乙個訊息佇列,存放訊息的地方。每乙個執行緒最多隻可以擁有乙個messagequeue資料結構。建立乙個執行緒的時候,並不會自動建立其messagequeue。通常使用乙個looper物件對該執行緒的mes...

Android的訊息機制

android的訊息機制主要是指handler的執行機制,而handler的執行離不開messagequeue和looper的支撐。其中messagequeue稱為訊息佇列,用作儲存一組訊息,並以佇列的形式對外提供插入和刪除工作 具體實現 使用單鏈表的結構來儲存訊息列表 messagequeue不能...

Android 的訊息機制

handler是android的訊息機制的上層介面,這使得在開發過程中只需要和handler互動即可,通過它可以很輕鬆地將乙個任務切換到handler所在的執行緒中去執行。android的訊息機制主要是指handler的執行機制,handler的執行需要底層的messageqeue和looper的支...