Android   发布时间:2022-04-28  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了Android Handler移除Message详解及实例代码大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

Android Handler移除message详解

问题:

1.removemessage(what)函数是否只能移除对应what值的message?

2.对于Delayed发送的message,能否提前remove?

代码测试:

@H_404_13@ 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);<span style="font-family: Arial,Helvetica,sans-serif;"> </span>

@H_404_13@ <span style="white-space:pre"></span><pre name="code" class="java"><span style="white-space:pre"> </span>mHandler.sendEmptymessageDelayed(1,2000);
@H_404_13@ 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=0message。

2. 在子线程中执行完

@H_404_13@ <span></span><pre name="code" class="java"><span style="white-space:pre"> </span>mHandler.sendEmptymessageDelayed(1,"handle sub-thread message...");

  之后,即可通过removeMesage(1)来移除消息,mHandler将不能接收到该条消息。

源码分析:

1.Android如何移除一条message?

查看源码可知,Handler.removemessage(int what)内部调用messageQueue.removemessage(this,what,null)

查看messageQueue的removemessage方法如下:

@H_404_13@ 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,源码如下:

@H_404_13@ 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 Handler移除Message详解及实例代码全部内容,希望文章能够帮你解决Android Handler移除Message详解及实例代码所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签: