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

时间:2017-12-14 15:47:01

标签: java android handler wear-os runnable

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

以下是我使用的代码:(一个简单的布尔状态,当false启动时设置为MotionEventPostDelayed上的Handler操作

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在必要时似乎不会被删除。 - &GT;如果我在视图上快速点击两次然后第三次按住它(那么3秒后出现的三个true的布尔状态为PostDelayed)我将执行我的特定操作代码3次 - &gt; Runnable事件未删除ACTION_UP任务。

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

如何正确销毁Runnable中后缀的handler

由于

1 个答案:

答案 0 :(得分:0)

handler.removeCallbacksAndMessages(null);

在removeCallbacksAndMessages的文档中,它说......

删除任何待处理的回调帖子,并发送obj为令牌的邮件。如果令牌为空,则将删除所有回调和消息。

removeCallbacks仅停止待处理的消息(Runnables)。如果你的runnable已经开始了,那么就没有停止它(至少不是这样)。

或者,你可以扩展Runnable类并给它一些像这样的kill开关:

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

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

      /* do your work */
   }

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

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

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