我有一个Handler从我的子活动被主活动调用。这个处理程序被子类用来postDelay一些可运行对象,我不能管理它们。现在,在onStop事件中,我需要在完成活动之前删除它们(不知何故我调用了finish(),但它仍然一次又一次地调用)。有没有办法从处理程序中删除所有回调?
当前回答
如果您没有Runnable引用,在第一次回调时,获取消息的obj,并使用removeCallbacksAndMessages()删除所有相关的回调。
其他回答
对于任何特定的可运行实例,调用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列表,因为它们被发布/执行了…或者看看在每个活动之间传递消息的另一个范例
希望有帮助!
正如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()删除所有相关的回调。
删除特定的可运行对象
handler.removeCallbacks(yourRunnable)
删除所有可运行程序
handler.removeCallbacksAndMessages(null)
请注意,应该在类范围内定义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)能够成功工作。
关键的句子是“在你的活动中定义它们为全局的,或者将你使用的内容分割”。
推荐文章
- 警告:API ' variable . getjavacompile()'已过时,已被' variable . getjavacompileprovider()'取代
- 安装APK时出现错误
- 在流中使用Java 8 foreach循环移动到下一项
- 访问限制:'Application'类型不是API(必需库rt.jar的限制)
- 用Java计算两个日期之间的天数
- 碎片中的onCreateOptionsMenu
- 如何配置slf4j-simple
- 在Jar文件中运行类
- 带参数的可运行?
- TextView粗体通过XML文件?
- 如何使线性布局的孩子之间的空间?
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- 我可以在Java中设置enum起始值吗?
- Java中的回调函数
- c#和Java中的泛型有什么不同?和模板在c++ ?