android message 代码,Android Handler移除Message详解及实例代码
Android Handler移除Message詳解
問題:
1.removeMessage(what)函數是否只能移除對應what值的Message?
2.對于Delayed發送的Message,能否提前remove?
代碼測試:
package javine.k.testhandler;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class TestHandlerActivity extends Activity implements OnClickListener {
private Button startBtn;
private Button endBtn;
public Handler threadHandler; //子線程Handler
private Handler mHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
threadHandler.sendEmptyMessageDelayed(1, 2000);
Log.d("info", "handle main-thread message...");
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
startBtn = (Button) findViewById(R.id.startButton);
endBtn = (Button) findViewById(R.id.endButton);
startBtn.setOnClickListener(this);
endBtn.setOnClickListener(this);
new Thread(new Runnable() {
@Override
public void run() {
HandlerThread handlerThread = new HandlerThread("handler");
handlerThread.start();
threadHandler = new Handler(handlerThread.getLooper()) {
@Override
public void handleMessage(Message msg) {
//mHandler.sendEmptyMessageDelayed(0, 2000);
mHandler.sendEmptyMessageDelayed(1, 2000);Log.d("info", "handle sub-thread message...");}};}}).start();}@Overridepublic void onClick(View v)
{// TODO Auto-generated method stubswitch (v.getId()) {case R.id.startButton:
//開始發送消息mHandler.sendEmptyMessage(1);break;case R.id.endButton:
//移除主線程Handler的消息mHandler.removeMessages(1);break;default:break;}}}
測試結果:
1. removeMassage(1)無法移除what=0的Message。
2. 在子線程中執行完
mHandler.sendEmptyMessageDelayed(1, 2000);Log.d("info", "handle sub-thread message...");
之后,即可通過removeMesage(1)來移除消息,mHandler將不能接收到該條消息。
源碼分析:
1.Android如何移除一條Message?
查看源碼可知,Handler.removeMessage(int what)內部調用MessageQueue.removeMessage(this, what, null)
查看MessageQueue的removeMessage方法如下:
void removeMessages(Handler h, int what, Object object) {
if (h == null) {
return;
}
synchronized (this) {
Message p = mMessages;
// Remove all messages at front.
while (p != null && p.target == h && p.what == what
&& (object == null || p.obj == object)) {
Message n = p.next;
mMessages = n;
p.recycle();
p = n;
}
// Remove all messages after front.
while (p != null) {
Message n = p.next;
if (n != null) {
if (n.target == h && n.what == what
&& (object == null || n.obj == object)) {
Message nn = n.next;
n.recycle();
p.next = nn;
continue;
}
}
p = n;
}
}
}
篩選要移除的Message的條件是:target(handler),what,object
該函數分兩步來移除Message:
1).移除在前端的符合條件的Message
2).移除后面的符合條件的Message
2.為何延遲發送的Message在延遲時間到達之前就可以被移除?
Handler.sendEmptyMessageDelayed() ---調用---> sendMessageAtTime() -----調用---> enqueueMessage() ----調用MessageQueue.enqueueMessage()
實際進行處理的就是MessageQueue,源碼如下:
boolean enqueueMessage(Message msg, long when) {
if (msg.isInUse()) {
throw new AndroidRuntimeException(msg + " This message is already in use.");
}
if (msg.target == null) {
throw new AndroidRuntimeException("Message must have a target.");
}
synchronized (this) {
if (mQuitting) {
RuntimeException e = new RuntimeException(
msg.target + " sending message to a Handler on a dead thread");
Log.w("MessageQueue", e.getMessage(), e);
return false;
}
msg.when = when;
Message p = mMessages;
boolean needWake;
if (p == null || when == 0 || when < p.when) {
// New head, wake up the event queue if blocked.
msg.next = p;
mMessages = msg;
needWake = mBlocked;
} else {
// Inserted within the middle of the queue. Usually we don't have to wake
// up the event queue unless there is a barrier at the head of the queue
// and the message is the earliest asynchronous message in the queue.
needWake = mBlocked && p.target == null && msg.isAsynchronous();
Message prev;
for (;;) {
prev = p;
p = p.next;
if (p == null || when < p.when) {
break;
}
if (needWake && p.isAsynchronous()) {
needWake = false;
}
}
msg.next = p; // invariant: p == prev.next
prev.next = msg;
}
// We can assume mPtr != 0 because mQuitting is false.
if (needWake) {
nativeWake(mPtr);
}
}
return true;
}
由上可知:MessageQueue會對需要延遲發送的Message排序,按照需要延遲的時間長短(when)。
即,雖然是延遲發送的消息,其實當你調用發送函數之后,Message就已經被添加到MessageQueue中去了。
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
總結
以上是生活随笔為你收集整理的android message 代码,Android Handler移除Message详解及实例代码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android4.0支持m3u8格式,【
- 下一篇: android strm,Android