国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發(fā)設(shè)計 > 正文

一定搞懂Handler消息處理機制系列之「02.Message入列」

2019-11-06 10:04:45
字體:
供稿:網(wǎng)友

Message入列

判斷新創(chuàng)建Message處于隊列中的位置,并插入相應位置

//截取自MessageQueue.enqueueMessage()方法來舉例(刪除了部分與此次無關(guān)代碼)boolean enqueueMessage(Message msg, long when) { synchronized (this) { //標記傳入的msg被使用 msg.markInUse(); msg.when = when; //創(chuàng)建臨時變量來儲存消息隊列中的Message對象 Message p = mMessages; boolean needWake; /* * 當消息隊列中沒有消息 * 或傳入Message的觸發(fā)時間為0時 * 或傳入Message的觸發(fā)時間小于當前消息隊列中的Message的觸發(fā)時間 */ if (p == null || when == 0 || when < p.when) { //把傳入的Message放入當前消息隊列中的Message之前 msg.next = p; //把當前消息隊列中的Message對象重置為傳入的Message對象 mMessages = msg; needWake = mBlocked; } else { /* * 當消息隊列中有消息 * 且傳入Message的觸發(fā)時間不為0時 * 且傳入Message的觸發(fā)時間大于當前消息隊列中的Message的觸發(fā)時間 */ needWake = mBlocked && p.target == null && msg.isAsynchronous(); //創(chuàng)建一個臨時變量 Message PRev; for (;;) { //儲存臨時變量p(當前消息隊列中的Messge) prev = p; //讓p指向自己在消息隊列中的下一條消息 p = p.next; //當p為null時,說明prev是當前消息隊列中的最后一條消息 //或者傳入Message的觸發(fā)時間小于p的觸發(fā)時間時終止循環(huán) if (p == null || when < p.when) { break; } } /* 此時的p滿足以下兩個條件中的一個: * 1.p為null時,說明prev是當前消息隊列中的最后一條消息(因為p為null,所以prev不為 null且prev的觸發(fā)時間小于傳入Message的觸發(fā)時間,所以傳入Message的為消息隊列中的最 后一條消息,prev為傳入Message的上一條消息) * 2.p的觸發(fā)時間大于傳入Message的觸發(fā)時間(因為p的觸發(fā)時間大于傳入Message的觸發(fā)時 間,所以p在消息隊列中是傳入Message的下一條消息,因為在上一次循環(huán)中沒有進入if語句, 所以prev不為null且觸發(fā)時間小于傳入Message對象的觸發(fā)時間,所以prev在消息隊列中處于 傳入Message的上一條) */ msg.next = p; prev.next = msg; } } return true; }

Message的獲取方式

Message的獲取方式除了new Message這種方式,Message類還提供了obtain方法來獲取Message

//Message類中有一個靜態(tài)全局變量來儲存空閑或者回收的Message對象private static Message sPool;public static Message obtain() { synchronized (sPoolSync) { if (sPool != null) { Message m = sPool; sPool = m.next; m.next = null; m.flags = 0; sPoolSize--; return m; } } return new Message(); }

這種方式是把靜態(tài)全局變量sPool(這里可以把這個Message看做當前消息池中的第一條消息)標記為未使用然后返回,如果sPool為null才會創(chuàng)建新的Message對象,這樣不會造成資源的浪費,避免創(chuàng)建太多Message對象。關(guān)于為什么sPool會是被回收的Message對象,上源碼:

//此方法為Message的回收方法 public void recycle() { //在回收的方法 recycleUnchecked(); }; void recycleUnchecked() { //這里在做一些重置的工作 flags = FLAG_IN_USE; what = 0; arg1 = 0; arg2 = 0; obj = null; replyTo = null; sendingUid = -1; when = 0; target = null; callback = null; data = null; synchronized (sPoolSync) { //當消息池里消息的數(shù)量小于消息池的最大容量時 if (sPoolSize < MAX_POOL_SIZE) { //重點?。?! /*把當前消息池中第一條消息(也就是sPool)置為當前消息的下一條消息(sPool為 全局靜態(tài)變量,所有Message都共用這一個sPool)*/ next = sPool; /*把當前消息置為消息池中第一條消息(因為上一步驟已經(jīng)把原來消息池中的第一條消息置為 了當前消息的下一條消息,現(xiàn)在把當前消息置為消息池中的第一條消息,所以sPool永遠代表 消息池中的第一條消息)*/ sPool = this; sPoolSize++; } } }

可以看出Message在回收過程中,只要消息池的數(shù)量小于消息池的最大容量時,就是把當前Message放入消息池中。

Message在MessageQueue隊列中存在的形式

從Message入列方式我們也看出,再有新消息進入隊列時,是先判斷新消息的觸發(fā)時間,找出消息應該插入消息隊列的位置,把這個位置的消息的next置為本條新消息,然后把新消息的next置為這個位置的消息的下一條消息。類似以下結(jié)構(gòu)(如果我理解有錯,歡迎指出)。

message

系列目錄:

一定搞懂Handler消息處理機制系列之「01.Handler消息發(fā)送」

一定搞懂Handler消息處理機制系列之「02.Message入列」

一定搞懂Handler消息處理機制系列之「03.MessageQueue與Looper的由來」

一定搞懂Handler消息處理機制系列之「04.Message是如何觸發(fā)的」


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 榆中县| 湘乡市| 阿拉善盟| 嘉祥县| 丹阳市| 堆龙德庆县| 西乌珠穆沁旗| 海原县| 红河县| 贞丰县| 沁源县| 双辽市| 兴化市| 孟州市| 义马市| 泰来县| 托克托县| 炎陵县| 全州县| 麻江县| 翁牛特旗| 电白县| 元江| 永昌县| 色达县| 云安县| 宁明县| 乐平市| 富宁县| 葵青区| 陇西县| 阿图什市| 利辛县| 辉县市| 金阳县| 长白| 华池县| 峨眉山市| 元朗区| 浦县| 师宗县|