removeCallbacks() 似乎没有删除 Handler 中指定的 Runnable

removeCallbacks() doesn't seems to delete the specified Runnable in Handler

我为智能手表开发了一个独立的应用程序,我想要一个 OnTouchListner 来检测 Touch 是否持续至少 3 秒并仅在这种情况下执行操作。

这是我使用的代码:(当 MotionEvent 启动并在 Handler 上执行 PostDelayed 操作时设置为 false 的简单布尔状态)

private int longClickDuration = 3000;
private boolean isLongPress = false;
static Runnable longTouchRunnable;

mContainerView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {

                longTouchRunnable = new Runnable() {
                    @Override
                    public void run() {
                        if (isLongPress) {
                            Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
                            long[] vibrationPattern = {0, 500, 50, 300};
                            //-1 - don't repeat
                            final int indexInPatternToRepeat = -1;
                            vibrator.vibrate(vibrationPattern, indexInPatternToRepeat);
                            // set your code here
                            setStateStarting(); //Block the GUI, only one click and waiting for tablet
                            presenter.onStartClick();
                            Log.d("Long","LONG CLICK PERFORMED");
                            // Don't forgot to add <uses-permission android:name="android.permission.VIBRATE" /> to vibrate.
                        }

                    }
                };

                switch (currentState) {
                    case START: {
                        if (event.getAction() == MotionEvent.ACTION_DOWN) {
                            isLongPress = true;
                            Log.e("Long touch","Start");
                            myUIHandler.postDelayed(longTouchRunnable, longClickDuration);
                        } else if (event.getAction() == MotionEvent.ACTION_UP) {
                            isLongPress = false;
                            myUIHandler.removeCallbacks(longTouchRunnable);
                            Log.e("Long touch", "Stop");
                        }
                        return true;
                    }
                }
                return false;
            }


        });

我的问题: 一切正常,希望 Runnable 在必要时似乎不会被删除。 --> 如果我在视图上快速单击两次然后第三次并按住它(因此布尔状态是 true 对于三个 PostDelayed 3 秒后出现)我将有我的具体操作代码执行了 3 次 --> Runnable 任务未随 ACTION_UP 事件一起删除。

信息:消息调试按预期提示...

如何正确销毁在 handler 中延迟的 Runnable

谢谢

handler.removeCallbacksAndMessages(null);

在 removeCallbacksAndMessages 的文档中说...

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

removeCallbacks 只停止挂起的消息(Runnables)。如果您的 runnable 已经启动,那么就无法停止它(至少不是这样)。

或者,您可以扩展 Runnable class 并为其提供某种终止开关,如下所示:

public class MyRunnable implements Runnable
{
   public boolean killMe = false;

   public void run()
   {
      if(killMe)
         return;

      /* do your work */
   }

   public void killRunnable()
   {
      killMe = true;
   }
}

这只会阻止它启动,但您偶尔可以检查 killMe 并退出。如果你正在循环运行(比如某种后台线程)你可以说:

while(!killMe) {
   /* do work */
}