日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

Android中Message機(jī)制的靈活應(yīng)用(一)

系統(tǒng) 2869 0

活用 Android 線程間通信的 Message 機(jī)制
1.1. Message

代碼在frameworks/base/core/java/android/Os/Message.java中。

Message.obtain 函數(shù):有多個(gè)obtain函數(shù),主要功能一樣,只是參數(shù)不一樣。作用是從Message Pool中取出一個(gè)Message,如果Message Pool中已經(jīng)沒有Message可取則新建一個(gè)Message返回,同時(shí)用對(duì)應(yīng)的參數(shù)給得到的Message對(duì)象賦值。

Message Pool : 大小為10個(gè);通過Message.mPool->(Message并且Message.next)-> (Message并且Message.next)-> (Message并且Message.next)...構(gòu)造一個(gè)Message Pool。Message Pool的第一個(gè)元素直接new出來,然后把Message.mPool(static類的static變量)指向它。其他的元素都是使用完的 Message通過Message的recycle函數(shù)清理后放到Message Pool(通過Message Pool最后一個(gè)Message的next指向需要回收的Message的方式實(shí)現(xiàn))。下圖為Message Pool的結(jié)構(gòu):

1.2. MessageQueue

MessageQueue 里面有一個(gè)收到的Message的對(duì)列:

MessageQueue.mMessages(static 變量)->( Message并且Message.next)-> ( Message并且Message.next)->...,下圖為接收消息的消息隊(duì)列:

上層代碼通過 Handler的sendMessage等函數(shù)放入一個(gè)message到MessageQueue里面時(shí)最終會(huì)調(diào)用MessageQueue的 enqueueMessage函數(shù)。enqueueMessage根據(jù)上面的接收的Message的隊(duì)列的構(gòu)造把接收到的Message放入隊(duì)列中。

MessageQueue 的removeMessages函數(shù)根據(jù)上面的接收的Message的隊(duì)列的構(gòu)造把接收到的Message從隊(duì)列中刪除,并且調(diào)用對(duì)應(yīng)Message對(duì)象的recycle函數(shù)把不用的Message放入Message Pool中。
1.3. Looper

Looper 對(duì)象的創(chuàng)建是通過prepare函數(shù),而且每一個(gè)Looper對(duì)象會(huì)和一個(gè)線程關(guān)聯(lián)

public static final void prepare() {


if (sThreadLocal.get() != null) {


throw new RuntimeException("Only one Looper may be created per thread");


}


sThreadLocal.set(new Looper());

}

Looper 對(duì) 象創(chuàng)建時(shí)會(huì)創(chuàng)建一個(gè)MessageQueue,主線程默認(rèn)會(huì)創(chuàng)建一個(gè)Looper從而有MessageQueue,其他線程默認(rèn)是沒有 MessageQueue的不能接收Message,如果需要接收Message則需要通過prepare函數(shù)創(chuàng)建一個(gè)MessageQueue。具體操 作請(qǐng)見示例代碼。

private Looper() {


mQueue = new MessageQueue();


mRun = true;


mThread = Thread.currentThread();

}

prepareMainLooper 函數(shù)只給主線程調(diào)用(系統(tǒng)處理,程序員不用處理),它會(huì)調(diào)用prepare建立Looper對(duì)象和MessageQueue。

public static final void prepareMainLooper() {
prepare();

setMainLooper(myLooper());

if (Process.supportsProcesses()) {


myLooper().mQueue.mQuitAllowed = false;

}

}

Loop 函 數(shù)從MessageQueue中從前往后取出Message,然后通過Handler的dispatchMessage函數(shù)進(jìn)行消息的處理(可見消息的處 理是Handler負(fù)責(zé)的),消息處理完了以后通過Message對(duì)象的recycle函數(shù)放到Message Pool中,以便下次使用,通過Pool的處理提供了一定的內(nèi)存管理從而加速消息對(duì)象的獲取。至于需要定時(shí)處理的消息如何做到定時(shí)處理,請(qǐng)見 MessageQueue的next函數(shù),它在取Message來進(jìn)行處理時(shí)通過判斷MessageQueue里面的Message是否符合時(shí)間要求來決 定是否需要把Message取出來做處理,通過這種方式做到消息的定時(shí)處理。

public static final void loop() {
Looper me = myLooper();

MessageQueue queue = me.mQueue;

while (true) {

Message msg = queue.next(); // might block

//if (!me.mRun) {

//
break;

//}

if (msg != null) {

if (msg.target == null) {

// No target is a magic identifier for the quit message.

return;

}

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();

}

}

}
1.4. Handler

Handler 的構(gòu)造函數(shù)表示Handler會(huì)有成員變量指向Looper和MessageQueue,后面我們會(huì)看到?jīng)]什么需要這些引用;至于callback是實(shí)現(xiàn)了Callback接口的對(duì)象,后面會(huì)看到這個(gè)對(duì)象的作用。

public Handler(Looper looper, Callback callback) {
mLooper = looper;

mQueue = looper.mQueue;

mCallback = callback;

}

public interface Callback {


public boolean handleMessage(Message msg);

}

獲取消息:直接通過Message的obtain方法獲取一個(gè)Message對(duì)象。

public final Message obtainMessage(int what, int arg1, int arg2, Object obj)

{
return Message.obtain(this, what, arg1, arg2, obj);

}

發(fā)送消息:通過MessageQueue的enqueueMessage把Message對(duì)象放到MessageQueue的接收消息隊(duì)列中

public boolean sendMessageAtTime(Message msg, long uptimeMillis)

{

boolean sent = false;

MessageQueue queue = mQueue;

if (queue != null) {
msg.target = this;

sent = queue.enqueueMessage(msg, uptimeMillis);

}

else {
RuntimeException e = new RuntimeException(

this + " sendMessageAtTime() called with no mQueue");

Log.w("Looper", e.getMessage(), e);

}

return sent;

}

線 程如何處理MessageQueue中接收的消息:在Looper的loop函數(shù)中循環(huán)取出MessageQueue的接收消息隊(duì)列中的消息,然后調(diào)用 Hander的dispatchMessage函數(shù)對(duì)消息進(jìn)行處理,至于如何處理(相應(yīng)消息)則由用戶指定(三個(gè)方法,優(yōu)先級(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ù),通過這個(gè)實(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);

}

}

Runnable 說明:Runnable只是一個(gè)接口,實(shí)現(xiàn)了這個(gè)接口的類對(duì)應(yīng)的對(duì)象也只是個(gè)普通的對(duì)象,并不是一個(gè)Java中的Thread。Thread類經(jīng)常使用Runnable,很多人有誤解,所以這里澄清一下。

從上可知以下關(guān)系圖:

其中清理Message是Looper里面的loop函數(shù)指把處理過的Message放到Message的Pool里面去,如果里面已經(jīng)超過最大值10個(gè),則丟棄這個(gè)Message對(duì)象。

調(diào)用Handler是指Looper里面的loop函數(shù)從MessageQueue的接收消息隊(duì)列里面取出消息,然后根據(jù)消息指向的Handler對(duì)象調(diào)用其對(duì)應(yīng)的處理方法。

Android中Message機(jī)制的靈活應(yīng)用(一)


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦?。?!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 漯河市| 仁寿县| 马鞍山市| 满洲里市| 海安县| 林周县| 泽普县| 万州区| 平潭县| 丹阳市| 祁门县| 二连浩特市| 特克斯县| 永和县| 和静县| 广饶县| 康乐县| 长寿区| 恩施市| 秦皇岛市| 栾城县| 新蔡县| 察雅县| 临城县| 东安县| 裕民县| 肃宁县| 鄢陵县| 临夏县| 拉萨市| 大名县| 富裕县| 亳州市| 玉山县| 政和县| 伽师县| 临湘市| 阜宁县| 灌云县| 汉中市| 佛山市|