關於Handler.removemessages方法
在閱讀老人的原始碼中,發現以下程式碼片段
private handleMessage(Message msg) {
switch(msg.what) {
case ACTION_XXX:
// do something...
this.removeMessages(ACTION_XXX);
break;
//other cases
}
}
1. 猜想
初步猜測其作用是為了處理某訊息後,清除在訊息佇列中等待的同類訊息,以達到防止在處理過程中重複傳送的目的
2. 驗證
於是寫一個demo驗證之(因為上述原始碼觸發效果過為複雜,所以不用此進行驗證)
mHandler.setHandlerCallBack(new MyHandler.MyHandlerCallBack() {
@Override
public void handleMessage(Message message) {
Log.i(TAG, "handleMessage: " + message.arg1);
if (message.what == ACTION_ODD) {
mMyHandler.removeMessages(ACTION_ODD);
}
}
});
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Message message = Message.obtain();
message.what = number % 2 == 0 ? ACTION_EVEN : ACTION_ODD;
message.arg1 = number;
// 將handleMessage延遲1s呼叫
mHandler.sendMessageDelayed(message, 1000);
number++;
}
});
快速點選Button後,觀察log日誌輸出
02-16 10:51:08.787 17454-17454/com.daijie.handlerapplication I/MainActivity: handleMessage: 0
02-16 10:51:08.958 17454-17454/com.daijie.handlerapplication I/MainActivity: handleMessage: 1
02-16 10:51:09.112 17454-17454/com.daijie.handlerapplication I/MainActivity: handleMessage: 2
02-16 10:51:09.489 17454-17454/com.daijie.handlerapplication I/MainActivity: handleMessage: 4
02-16 10:51:09.762 17454-17454/com.daijie.handlerapplication I/MainActivity: handleMessage: 6
02-16 10:51:10.100 17454-17454/com.daijie.handlerapplication I/MainActivity: handleMessage: 8
02-16 10:51:10.237 17454-17454/com.daijie.handlerapplication I/MainActivity: handleMessage: 9
3. 推論
從日誌輸出可以得知偶數全部被輸出,而1~9中的奇數被過濾了
可以推斷handleMessage在輸出Message.what==1的log結束後,呼叫Handler.removeMessages將Message.what為ACTION_ODD從訊息佇列中移除,所以中間的訊息被過濾掉了。
4. 檢視原始碼
檢視原始碼是最好的驗證方式,所以先檢視Handler的removeMessages方法原始碼
// Handler.java
public final void removeMessages(int what) {
mQueue.removeMessages(this, what, null);
}
可以看出,這裡實際上是移除訊息佇列的message,再看看MessageQueue中的removeMessages方法原始碼
// MessageQueue.java
void removeMessages(Handler h, int what, Object object) {
if (h == null) {
return;
}
synchronized (this) {
Message p = mMessages;
// 原始碼註釋,Remove all messages at front.
// 根據上面傳入的引數,p!=null成立,p.target == h成立,object == null 成立
// 即此處可等同為p.what == what
// 此處程式碼即找到第一個p.what == what的訊息並將其移除
while (p != null && p.target == h && p.what == what
&& (object == null || p.obj == object)) {
Message n = p.next;
mMessages = n;
p.recycleUnchecked();
p = n;
}
// Remove all messages after front.
// 此處即為移除找到第一個後的Message
while (p != null) {
Message n = p.next;
if (n != null) {
// 同上,此處也可以等同為p.what == what
if (n.target == h && n.what == what
&& (object == null || n.obj == object)) {
Message nn = n.next;
n.recycleUnchecked();
p.next = nn;
continue;
}
}
p = n;
}
}
}
由原始碼中可以看出,MessageQueue將Message.what與函式傳入的what相同的Message從佇列中移除,和推論相符
這是本人第一次進行探討,如有什麼錯誤,請在評論區進行糾正。
相關文章
- 問:關於synchronized方法synchronized
- 關於Promise後續的方法。Promise
- 關於Java中的equals方法Java
- 關於InputMethodManager的使用方法
- 關於檔案的open方法
- Activity關於onConfigurationChanged方法
- 關於我做事的方法經驗
- 關於java實現同步的方法Java
- 關於Oracle死鎖處理方法Oracle
- 關於JMX中MBeanServer的invoke()方法BeanServer
- 關於view.layout方法引數View
- 關於jdon的PageIterator的getPageIterator方法
- 關於ubuntu修改hosts檔案的方法Ubuntu
- 關於python訪問字典的方法Python
- Java 面試題關於方法的重寫Java面試題
- 關於如何獲取資料的方法
- 關於innodb中查詢的定位方法
- 關於ASM的failgroup概念的探索方法ASMAI
- Java--- 關於null的處理若干方法JavaNull
- 關於ES5陣列方法總結陣列
- 求救:關於EJB單步除錯的方法除錯
- 關於oracle表空間的規劃方法Oracle
- 關於字串分類抽取的幾個方法字串
- 請教:關於物件導向的分析方法物件
- 關於新版jquery用on()方法代替live方法的正確使用方式jQuery
- 關於IT,關於技術
- 關於 artisan migrants Could not find drive 解決方法
- 關於快速排序中元素調整方法的分析排序
- JavaScript關於陣列的一些方法整理JavaScript陣列
- 關於npm install失敗的解決方法NPM
- 關於Css的垂直居中的一些方法CSS
- 關於Java的取時間方法的爭論Java
- 關於在類陣列中使用陣列方法陣列
- jQuery關於DOM操作節點一些方法jQuery
- 關於法學考研(刑法),我的學習方法
- 關於給apache新增PHP擴充套件的方法ApachePHP套件
- 關於如何解釋機器學習的一些方法機器學習
- 頁面找不到js方法的原因,關於EasyUIJSUI