我有一个Handler从我的子活动被主活动调用。这个处理程序被子类用来postDelay一些可运行对象,我不能管理它们。现在,在onStop事件中,我需要在完成活动之前删除它们(不知何故我调用了finish(),但它仍然一次又一次地调用)。有没有办法从处理程序中删除所有回调?
当前回答
对于任何特定的可运行实例,调用Handler.removeCallbacks()。注意,它使用Runnable实例本身来决定取消哪些回调,因此,如果每次发布帖子时都要创建一个新实例,则需要确保对要取消的Runnable的引用是准确的。例子:
Handler myHandler = new Handler();
Runnable myRunnable = new Runnable() {
public void run() {
//Some interesting task
}
};
你可以调用myHandler。postDelayed(myRunnable, x)在你的代码中的其他地方发布另一个回调到消息队列,并使用myHandler.removeCallbacks(myRunnable)删除所有挂起的回调
不幸的是,你不能简单地“清除”处理程序的整个MessageQueue对象,即使你请求与它关联的MessageQueue对象,因为添加和删除项目的方法是包保护的(只有类在android。OS包可以调用它们)。你可能需要创建一个瘦Handler子类来管理一个Runnables列表,因为它们被发布/执行了…或者看看在每个活动之间传递消息的另一个范例
希望有帮助!
其他回答
根据我的经验,这样做很有效!
handler.removeCallbacksAndMessages(null);
在removeCallbacksAndMessages的文档中它说…
删除所有obj为token的回调和已发送消息的挂起帖子。如果token为空,所有回调和消息将被删除。
定义一个新的处理程序和runnable:
private Handler handler = new Handler(Looper.getMainLooper());
private Runnable runnable = new Runnable() {
@Override
public void run() {
// Do what ever you want
}
};
呼叫延迟:
handler.postDelayed(runnable, sleep_time);
从你的处理器中移除你的回调函数:
handler.removeCallbacks(runnable);
请注意,应该在类范围内定义Handler和Runnable,以便只创建一次。removecallbacks (Runnable)可以正常工作,除非多次定义它们。为了更好地理解,请看下面的例子:
错误方式:
public class FooActivity extends Activity {
private void handleSomething(){
Handler handler = new Handler();
Runnable runnable = new Runnable() {
@Override
public void run() {
doIt();
}
};
if(shouldIDoIt){
//doIt() works after 3 seconds.
handler.postDelayed(runnable, 3000);
} else {
handler.removeCallbacks(runnable);
}
}
public void onClick(View v){
handleSomething();
}
}
如果你调用onClick(..)方法,你永远不会在doIt()方法调用之前停止它。因为每次都会创建新的Handler和新的Runnable实例。通过这种方式,您丢失了属于处理程序和可运行实例的必要引用。
正确方法:
public class FooActivity extends Activity {
Handler handler = new Handler();
Runnable runnable = new Runnable() {
@Override
public void run() {
doIt();
}
};
private void handleSomething(){
if(shouldIDoIt){
//doIt() works after 3 seconds.
handler.postDelayed(runnable, 3000);
} else {
handler.removeCallbacks(runnable);
}
}
public void onClick(View v){
handleSomething();
}
}
通过这种方式,您不会丢失实际的引用,并且removeCallbacks(runnable)能够成功工作。
关键的句子是“在你的活动中定义它们为全局的,或者将你使用的内容分割”。
正如josh527所说,handler.removeCallbacksAndMessages(null);可以工作。 但是为什么呢? 如果您看一下源代码,就可以更清楚地理解它。 有3种类型的方法可以从处理器(MessageQueue)中删除回调/消息:
通过回调(和令牌)删除 通过留言删除。什么(和标志) 通过令牌删除
java(留下一些重载方法)
/**
* Remove any pending posts of Runnable <var>r</var> with Object
* <var>token</var> that are in the message queue. If <var>token</var> is null,
* all callbacks will be removed.
*/
public final void removeCallbacks(Runnable r, Object token)
{
mQueue.removeMessages(this, r, token);
}
/**
* Remove any pending posts of messages with code 'what' and whose obj is
* 'object' that are in the message queue. If <var>object</var> is null,
* all messages will be removed.
*/
public final void removeMessages(int what, Object object) {
mQueue.removeMessages(this, what, object);
}
/**
* Remove any pending posts of callbacks and sent messages whose
* <var>obj</var> is <var>token</var>. If <var>token</var> is null,
* all callbacks and messages will be removed.
*/
public final void removeCallbacksAndMessages(Object token) {
mQueue.removeCallbacksAndMessages(this, token);
}
java做真正的工作:
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.recycleUnchecked();
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.recycleUnchecked();
p.next = nn;
continue;
}
}
p = n;
}
}
}
void removeMessages(Handler h, Runnable r, Object object) {
if (h == null || r == null) {
return;
}
synchronized (this) {
Message p = mMessages;
// Remove all messages at front.
while (p != null && p.target == h && p.callback == r
&& (object == null || p.obj == object)) {
Message n = p.next;
mMessages = n;
p.recycleUnchecked();
p = n;
}
// Remove all messages after front.
while (p != null) {
Message n = p.next;
if (n != null) {
if (n.target == h && n.callback == r
&& (object == null || n.obj == object)) {
Message nn = n.next;
n.recycleUnchecked();
p.next = nn;
continue;
}
}
p = n;
}
}
}
void removeCallbacksAndMessages(Handler h, Object object) {
if (h == null) {
return;
}
synchronized (this) {
Message p = mMessages;
// Remove all messages at front.
while (p != null && p.target == h
&& (object == null || p.obj == object)) {
Message n = p.next;
mMessages = n;
p.recycleUnchecked();
p = n;
}
// Remove all messages after front.
while (p != null) {
Message n = p.next;
if (n != null) {
if (n.target == h && (object == null || n.obj == object)) {
Message nn = n.next;
n.recycleUnchecked();
p.next = nn;
continue;
}
}
p = n;
}
}
}
如果您没有Runnable引用,在第一次回调时,获取消息的obj,并使用removeCallbacksAndMessages()删除所有相关的回调。
推荐文章
- 如何分割逗号分隔的字符串?
- Java字符串—查看字符串是否只包含数字而不包含字母
- 如何隐藏动作栏之前的活动被创建,然后再显示它?
- Mockito.any()传递带有泛型的接口
- 在IntelliJ 10.5中运行测试时,出现“NoSuchMethodError: org.hamcrest. matcher . descripbemismatch”
- 是否有一种方法以编程方式滚动滚动视图到特定的编辑文本?
- 使用String.split()和多个分隔符
- Java数组有最大大小吗?
- 在Android中将字符串转换为Uri
- 从JSON生成Java类?
- 为什么java.util.Set没有get(int index)?
- Swing和AWT的区别是什么?
- 如何在NestedScrollView内使用RecyclerView ?
- 为什么Java流是一次性的?
- 移动到另一个EditText时,软键盘下一步点击Android