我为智能手表开发了一个独立的应用程序,我想拥有一个OnTouchListner
,该应用程序检测Touch
是否持续了至少3秒并仅在这种情况下执行操作。
这是我使用的代码:(一个简单的布尔态,当MotionEvent
启动时设置为false
,并且在Handler
上进行PostDelayed
操作)
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
在必要时似乎不会删除。 ->如果我在视图上快速单击两次,然后第三次持有并持有(因此,布尔状态为三个PostDelayed
的true
),我将执行3次特定的操作代码 ->>Runnable
任务未在ACTION_UP
事件中删除。
信息:消息调试是按预期提示的...
我如何正确销毁在handler
中延迟的Runnable
?
谢谢
handler.removeCallbacksAndMessages(null);
在文档中的删除backsandmessages中,它说...
删除所有待定的回调帖子,并发送了其OBJ为令牌的消息。如果令牌为null,则所有回调和消息将被删除。
removeCallbacks
仅停止待处理消息(Runnables)。如果您的可运行能力已经开始,那么就不会停止它(至少不是这样)。
另外,您可以扩展可运行的类,并以这样的方式给予某种杀戮开关:
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 */
}