亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Android中Message機制的靈活應用(一)

系統 2501 0

活用 Android 線程間通信的 Message 機制
1.1. Message

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

Message.obtain 函數:有多個obtain函數,主要功能一樣,只是參數不一樣。作用是從Message Pool中取出一個Message,如果Message Pool中已經沒有Message可取則新建一個Message返回,同時用對應的參數給得到的Message對象賦值。

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

1.2. MessageQueue

MessageQueue 里面有一個收到的Message的對列:

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

上層代碼通過 Handler的sendMessage等函數放入一個message到MessageQueue里面時最終會調用MessageQueue的 enqueueMessage函數。enqueueMessage根據上面的接收的Message的隊列的構造把接收到的Message放入隊列中。

MessageQueue 的removeMessages函數根據上面的接收的Message的隊列的構造把接收到的Message從隊列中刪除,并且調用對應Message對象的recycle函數把不用的Message放入Message Pool中。
1.3. Looper

Looper 對象的創建是通過prepare函數,而且每一個Looper對象會和一個線程關聯

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 對 象創建時會創建一個MessageQueue,主線程默認會創建一個Looper從而有MessageQueue,其他線程默認是沒有 MessageQueue的不能接收Message,如果需要接收Message則需要通過prepare函數創建一個MessageQueue。具體操 作請見示例代碼。

private Looper() {


mQueue = new MessageQueue();


mRun = true;


mThread = Thread.currentThread();

}

prepareMainLooper 函數只給主線程調用(系統處理,程序員不用處理),它會調用prepare建立Looper對象和MessageQueue。

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

setMainLooper(myLooper());

if (Process.supportsProcesses()) {


myLooper().mQueue.mQuitAllowed = false;

}

}

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

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 的構造函數表示Handler會有成員變量指向Looper和MessageQueue,后面我們會看到沒什么需要這些引用;至于callback是實現了Callback接口的對象,后面會看到這個對象的作用。

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

mQueue = looper.mQueue;

mCallback = callback;

}

public interface Callback {


public boolean handleMessage(Message msg);

}

獲取消息:直接通過Message的obtain方法獲取一個Message對象。

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

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

}

發送消息:通過MessageQueue的enqueueMessage把Message對象放到MessageQueue的接收消息隊列中

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函數中循環取出MessageQueue的接收消息隊列中的消息,然后調用 Hander的dispatchMessage函數對消息進行處理,至于如何處理(相應消息)則由用戶指定(三個方法,優先級從高到低:Message里 面的Callback,一個實現了Runnable接口的對象,其中run函數做處理工作;Handler里面的mCallback指向的一個實現了 Callback接口的對象,里面的handleMessage進行處理;處理消息Handler對象對應的類繼承并實現了其中 handleMessage函數,通過這個實現的handleMessage函數處理消息)。

public void dispatchMessage(Message msg) {
if (msg.callback != null) {

handleCallback(msg);

} else {

if (mCallback != null) {

if (mCallback.handleMessage(msg)) {

return;

}

}

handleMessage(msg);

}

}

Runnable 說明:Runnable只是一個接口,實現了這個接口的類對應的對象也只是個普通的對象,并不是一個Java中的Thread。Thread類經常使用Runnable,很多人有誤解,所以這里澄清一下。

從上可知以下關系圖:

其中清理Message是Looper里面的loop函數指把處理過的Message放到Message的Pool里面去,如果里面已經超過最大值10個,則丟棄這個Message對象。

調用Handler是指Looper里面的loop函數從MessageQueue的接收消息隊列里面取出消息,然后根據消息指向的Handler對象調用其對應的處理方法。

Android中Message機制的靈活應用(一)


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

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

【本文對您有幫助就好】

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

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 欧美日韩国产最新一区二区 | 日韩精品欧美精品中文精品 | 国产福利第一页 | 亚洲一区二区三区久久 | 亚洲国内 | 国产三级在线精品男人的天堂 | 久久久精品日本一区二区三区 | 在线成人天天鲁夜啪视频 | 久久精品免费大片国产大片 | 日本成本人在线观看免费视频 | 久久99精品久久久久久国产越南 | 99久久精品国产国产毛片 | 久久综合桃花网 | 中文字幕在线一区二区三区 | 俺去久久 | 亚洲综合五月 | 国产一区免费在线观看 | 亚洲美女黄视频 | 无遮挡又黄又爽又色1000部 | 色婷婷中文字幕 | 国产一区二区三区免费在线视频 | 443hk四虎 在线观看 | 99re这里只有热视频 | 国产欧美久久久精品 | 精品久久久久国产免费 | 国产精品天天操 | 99热久久国产综合精品久久国产 | 国产一区二区网站 | 奇米视频在线观看 | 一级成人a毛片免费播放 | 五月天婷婷在线观看 | 欧美国产伦久久久久 | 国产三级做爰高清视频a | 国产一区二区三区不卡免费观看 | 中文字幕福利视频 | 亚洲欧洲日本在线观看 | 热思思久久 | 波多野给衣一区二区三区 | 免费人成激情视频在线看 | 中文字幕日韩精品在线 | 成人免费观看www视频 |