从 android 中的加速度计读取后,一行代码正在循环



这是我在应用程序中遇到的唯一问题。 默认情况下为 n=0,如果加速度计的重力值高于某个值,则将设置为 1。一旦 n=1(检测到的重力足够高),将调用方法 "action()"。由于加速度计的重力值变化非常快,我需要调用 action() 并稍等片刻,然后再将 n 改回 0,否则 action() 将连续调用几次。

我尝试在调用操作后和将 n 更改为 0 之前使用 sleep(),但它不起作用。然后我尝试使用倒数计时器 5 秒,它只是循环动作();非常快5秒才停下来。可能是我对 android 倒数计时器缺乏了解,这很奇怪,因为我在代码的其他部分使用了它并且它运行良好。

if(n == 1){
if (state == true) {
action();
new CountDownTimer(5000, 1000) {
@Override
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
n = 0;
}
}.start();
}
}

我只需要一种方法,只调用一次 action(),然后将 n 设置为 0,以便为从加速度计再次读取做好准备。

谢谢!

我想我明白你想实现的目标,这可能只是荷马辛普森的"哦!"时刻......

当 n=1 时,你想调用action(),那么action()将继续被调用为 n=1 和 state=true。您的倒数计时器将保持 n=1,直到 5 秒过去,此时它被设置为零,以防止调用action()。此外,您一遍又一遍地创建新的倒数计时器,只要 n=1 且状态 = true。

您真正想做的是立即将n设置为零,state设置为 false。如果n再次变为 1,则state将阻止调用action()。然后在倒计时结束后将state设置回 true,这将允许再次调用action。如果state在其他地方使用,那么您可能需要另一个布尔变量用作控件。这样,加速度计可以随时将n设置为 1,但在state为真之前,您不会关心。

if(n == 1){
if (state == true) {
n=0;
state=false;
action();
new CountDownTimer(5000, 1000) {
@Override
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
state=true;
}
}.start();
}
}

@DigitalNinja答案更适合您发布的代码 - 但请考虑以下替代方案:

定义一个类:

public class ActionTrigger {
private int latchTimeInMillis;
private long lastTrigger = 0;
public ActionTrigger(int latchTimeInMillis)
{
this.latchTimeInMillis = latchTimeInMillis;
}
/** Invoke 'action' on first trigger or after desired interval. */       
public void trigger()
{
long cTime = System.currentTimeInMillis();
if ((cTime - lastTrigger) > latchTimeInMillis)
{
action();
lastTrigger = cTime;
}
}
}

在代码初始化期间,创建一个实例:

ActionTrigger myActionTrigger = new ActionTrigger(5000);

您的 OP 代码变为:

// if current gravity reading exceeds threshold
if(n == 1) {
// the associated 'action' only gets called initially or after desired interval
myActionTrigger.trigger();
}

如果要泛化ActionTrigger并允许不同的"操作",则可以在构造函数中定义回调机制,例如:

public interface ActionTriggerCallack
{
public void onTrigger();
}

并将回调添加为构造函数参数

public ActionTrigger(int latchTimeInMillis, ActionTriggerCallback cb) {...}

而不是直接调用"操作"调用:

cb.onTrigger();

并更改原始初始化:

ActionTrigger myActionTrigger = new ActionTrigger(5000, 
new ActionTriggerCallback() {
public void onTrigger() { action(); } 
});

最新更新