我有一个Handler从我的子活动被主活动调用。这个处理程序被子类用来postDelay一些可运行对象,我不能管理它们。现在,在onStop事件中,我需要在完成活动之前删除它们(不知何故我调用了finish(),但它仍然一次又一次地调用)。有没有办法从处理程序中删除所有回调?
当前回答
根据我的经验,这样做很有效!
handler.removeCallbacksAndMessages(null);
在removeCallbacksAndMessages的文档中它说…
删除所有obj为token的回调和已发送消息的挂起帖子。如果token为空,所有回调和消息将被删除。
其他回答
对于任何特定的可运行实例,调用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;
}
}
}
请注意,应该在类范围内定义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)能够成功工作。
关键的句子是“在你的活动中定义它们为全局的,或者将你使用的内容分割”。
定义一个新的处理程序和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.removeCallbacks(yourRunnable)
删除所有可运行程序
handler.removeCallbacksAndMessages(null)
推荐文章
- 如何在java中格式化持续时间?(如格式H:MM:SS)
- urlencoder .encode(字符串)已弃用,我应该使用什么代替?
- javax.transaction.Transactional vs . org.springframework.transaction.annotation.Transactional
- Java 8接口方法中不允许“同步”的原因是什么?
- 如何找到Java堆大小和内存使用(Linux)?
- 改变开关的“开”色
- 以编程方式将EditText的输入类型从PASSWORD更改为NORMAL,反之亦然
- 如何在隐藏和查看密码之间切换
- 在Android上调整一个大的位图文件到缩放输出文件
- 使用Enum实现单例(Java)
- 如何更改Android版本和代码版本号?
- Android Studio突然无法解析符号
- 应用程序重新启动而不是恢复
- RabbitMQ与通道和连接之间的关系
- buildSessionFactory()配置方法在Hibernate中已弃用?