取消handler.postdelayed进程


259

我正在handler.postDelayed()创建一个等待期,直到我的应用程序进入下一阶段。在等待期间,我将显示一个带有进度条和取消按钮的对话框。

我的问题是我找不到在时间过去之前取消postDelayed任务的方法。



希望此要点可以帮助gist.github.com/imammubin/a587192982ff8db221da14d094df6fb4 MainActivity作为具有处理程序和可运行功能的屏幕启动器,可运行的登录页面或具有Firebase基本首选项登录用户的供稿页面。
Mubin

Answers:


479

我这样做是为了发布延迟的可运行对象:

myHandler.postDelayed(myRunnable, SPLASH_DISPLAY_LENGTH); 

并删除它: myHandler.removeCallbacks(myRunnable);


74
如果您有能力取消处理程序上的所有回调和消息,并且不想保留对可运行对象的引用,则此问题的已接受答案中的第三点是无论如何似乎都适合我的情况的另一种选择:stackoverflow。 com / questions / 11299440 /… (本质上是调用myHandler.removeCallbacksAndMessages(null);)
Mick

removeCallbacksAndMessages可以解决问题,但就我个人而言,我更喜欢对计划的可运行对象进行控制。实例化和处理一对Runnable不会杀死您的应用程序性能。否则,如果您需要两个或三个以上的Runnable,则可能需要更强大的功能,恕我直言。
andrea.rinaldi

59

如果确实有多个内部/匿名可运行对象传递给同一处理程序,并且您想在同一事件使用时取消全部

handler.removeCallbacksAndMessages(null);

根据文档,

删除obj为令牌的回调和已发送消息的所有未决帖子。如果token为null,则将删除所有回调和消息。


这将删除所有可运行的回调一次。否则,请致电 removeCallbacks(callback) 以删除特定的回调
FindOutIslamNow

18

另一种方法是处理Runnable本身:

Runnable r = new Runnable {
    public void run() {
        if (booleanCancelMember != false) {
            //do what you need
        }
    }
}

14
booleanCancelMember是否必须是最终的,这意味着它不能被更改,因此对于此目的毫无用处?
隐身直升机2011年

9
@stealthcopter不,不是必须的。
Benoit Jadinon

7
@pablisco即使Runnable是匿名的也不一定必须是最终的。它可以是封闭类中的成员。
马丁

6
不能拒绝,但是要小心。使用这种方法,如果多个Runnable的发布被延迟,则可能会遇到令人讨厌的竞赛条件。这不会取消Runnable,因此是否执行该代码取决于每个发布的Runnable 在特定时刻的booleanCancelMember值。这可能很快变得不可预测。
丹尼斯K

1
如果Runnable不是匿名的,则意味着我有r对此的引用(在这种情况下),这意味着我可以使用myHandler.removeCallbacks(r);。如果Runnable是匿名的,则该标志将成为封闭类的成员,这意味着我需要对该对象的引用才能更改该标志,这意味着r无论如何我也将不得不拥有该标志,这意味着我可以做到myHandler.removeCallbacks(r);。如果我正在这样做,myHandler.removeCallbacks(r);那么根本不需要这样的标记。我想念什么吗?
nacho4d

1

这是一个为延迟动作提供取消方法的类

public class DelayedAction {

private Handler _handler;
private Runnable _runnable;

/**
 * Constructor
 * @param runnable The runnable
 * @param delay The delay (in milli sec) to wait before running the runnable
 */
public DelayedAction(Runnable runnable, long delay) {
    _handler = new Handler(Looper.getMainLooper());
    _runnable = runnable;
    _handler.postDelayed(_runnable, delay);
}

/**
 * Cancel a runnable
 */
public void cancel() {
    if ( _handler == null || _runnable == null ) {
        return;
    }
    _handler.removeCallbacks(_runnable);
}}

0

当我通过布尔值将其传递给延迟运行的帖子中的内部调用CancelCallBacks(this)时,它对我有用

Runnable runnable = new Runnable(){
    @Override
    public void run() {
        Log.e("HANDLER", "run: Outside Runnable");
        if (IsRecording) {
            Log.e("HANDLER", "run: Runnable");
            handler.postDelayed(this, 2000);
        }else{
            handler.removeCallbacks(this);
        }
    }
};

3
您的代码中没有“ CancelCallBacks”。也许是因为它不存在?:)
令人难以置信的

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.