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.uti
l.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 handle
message(android
.os.message msg)
{
threadHandler.sendEmpty
messageDelayed(1,2000
);
Log.d("info","handle main-thread
message..."
);
};
};
@Override
protected void onCreate(Bundle savedInstanceStat
E) {
// TODO Auto-generated method
stub
super
.onCreate(savedInstanceStat
E);
setContentView(R.layout.main
);
startBtn = (Button) findViewById(R.id.startButton
);
endBtn = (Button) findViewById(R.i
d.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 handle
message(
message msg)
{
//mHandler.sendEmpty
messageDelayed(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.sendEmpty
messageDelayed(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.sendEmpty
message
(1);break;case R.i
d.endButton:
//移除主线程Handler的消息mHandler.remove
messages
(1);break;default:break;}}}
测试结果:
1. removeMassage(1)无法移除what=0的message。
2. 在子线程中执行完
@H_
404_13@
<span></span><pre name="code" class="java"><span style="white-space:pre">
</span>mHandler.sendEmpty
messageDelayed(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 remove
messages(Handler h,int
what,Ob
ject ob
ject)
{
if (h == null)
{
return;
}
synchronized (this)
{
message p = m
messages;
// Remove all
messages at front.
while (p
!= null && p.target == h && p.
what ==
what
&& (ob
ject == null || p
.obj == ob
ject))
{
message n = p.next;
m
messages = 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
&& (ob
ject == null || n
.obj == ob
ject))
{
message nn = n.next;
n.recycle(
);
p.next = nn;
con
Tinue;
}
}
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 enqueue
message(
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 (mQuit
Ting)
{
RuntimeException e = new RuntimeException(
msg.target + " sending
message to a Handler on a dead thread"
);
Log.w("
messageQueue",e.get
message(),
E);
return
false;
}
msg.when = when;
message p = m
messages;
Boolean needWake;
if (p == null || when == 0 || when < p.when)
{
// New head,wake up the event queue if blocked.
msg.next = p;
m
messages = 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 mQuit
Ting is
false.
if (needWak
E) {
nativeWake(mPtr
);
}
}
return true;
}
由上可知:messageQueue会对需要延迟发送的message排序,按照需要延迟的时间长短(when)。
即,虽然是延迟发送的消息,其实当你调用发送函数之后,message就已经被添加到messageQueue中去了。
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
大佬总结
以上是大佬教程为你收集整理的Android Handler移除Message详解及实例代码全部内容,希望文章能够帮你解决Android Handler移除Message详解及实例代码所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。