【问题标题】:cancelling a handler.postdelayed process取消 handler.postdelayed 进程
【发布时间】:2011-05-21 16:22:06
【问题描述】:

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

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

【问题讨论】:

标签: android android-handler postdelayed


【解决方案1】:

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

myHandler.postDelayed(myRunnable, SPLASH_DISPLAY_LENGTH); 

然后删除它:myHandler.removeCallbacks(myRunnable);

【讨论】:

  • 如果您有能力取消处理程序上的所有回调和消息,并且不想保留对可运行对象的引用,则该问题已接受答案中的第三点是另一种选择无论如何都适合我的情况:stackoverflow.com/questions/11299440/…(本质上是调用 myHandler.removeCallbacksAndMessages(null); )
  • removeCallbacksAndMessages 可以解决问题,但我个人更喜欢控制预定的可运行文件。实例化和处理一对 Runnable 不会影响您的应用性能;否则,如果您需要两个或三个以上的 Runnable,您可能需要更强大的东西,恕我直言。
【解决方案2】:

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

handler.removeCallbacksAndMessages(null);

根据文档,

删除所有待处理的回调和已发送消息,其 obj 为 令牌。如果 token 为 null,所有的回调和消息都会被移除。

【讨论】:

  • 这将删除所有可运行的回调一次。否则,调用removeCallbacks(callback) 删除特定回调
【解决方案3】:

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

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

【讨论】:

  • 不会 booleanCancelMember 必须是最终的,这意味着它无法更改,因此对此无用?
  • @stealthcopter 不,不必如此。
  • @pablisco 即使 Runnable 是匿名的,它也不必是最终的。它可以是封闭类中的成员。
  • 不要对此投反对票,但要小心。使用这种方法,如果延迟发布多个 Runnable,您可能会遇到令人讨厌的竞争条件。这不会取消 Runnable,因此该代码是否将被执行取决于 booleanCancelMember 在 每个 发布的 Runnable 的特定时刻的值。这可能很快就会变得不可预测。
  • 如果 Runnable 不是匿名的,这意味着我有对它的引用(在这种情况下为r),这意味着我可以使用myHandler.removeCallbacks(r);。如果 Runnable 是匿名的,那么标志将是封闭类中的成员,这意味着我需要对该对象的引用来更改标志,这意味着无论如何我都必须拥有r,这意味着我可以做@ 987654325@。如果我在做myHandler.removeCallbacks(r);,那么根本不需要这样的标志。我错过了什么吗?
【解决方案4】:

这很简单,只要使用下面的语句,它就会取消 Handler 的所有 CallBacks 并删除 Runnable 的所有待处理帖子。

handler.removeCallbacksAndMessages(null);

【讨论】:

    【解决方案5】:

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

    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);
    }}
    

    【讨论】:

      【解决方案6】:

      当我通过布尔值传递延迟可运行的帖子中调用 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);
              }
          }
      };
      

      【讨论】:

      • 您的代码中没有“CancelCallBacks”。也许是因为它不存在? :)
      【解决方案7】:

      希望这个要点能帮助https://gist.github.com/imammubin/a587192982ff8db221da14d094df6fb4

      MainActivity 作为具有处理程序和可运行功能的屏幕启动器,可运行运行到登录页面或带有基本偏好登录用户的提要页面和 firebase。

      【讨论】:

        猜你喜欢
        • 2011-11-16
        • 2013-09-24
        • 2014-05-08
        • 1970-01-01
        • 2019-06-11
        • 2021-03-06
        • 1970-01-01
        • 2016-05-31
        相关资源
        最近更新 更多