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 */
}
我为智能手表开发了一个独立的应用程序,我想要一个 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 */
}