2011-03-26 118 views
3

我在我的Android应用程序中使用可运行程序来更新倒数计时器,如下面的代码所示。它似乎工作,但我注意到我的计时器比预期的要花几秒钟。例如,如果它应该倒数3分钟,则需要3分5秒。我尝试在服务中使用计时器来管理主要活动中的倒计时显示。计时器/服务按预期工作。Runnable执行速度比预期慢

为什么不运行runnable/postDelayed()正确的时间?是postDelayed()时间可靠吗? runnable递减一个变量,然后使用它来更新EditTextsetText()setText()花费的时间太长(一秒钟的一小部分),所以runnable确实每隔1.x秒运行一次?

Handler handler = new Handler(); 
Runnable r = new Runnable() { 
    public void run() { 
     // decrement the time remaining and update the display 
     handler.postDelayed(this, 1000); 
    } 
}; 
... 
// start the runnable 
handler.postDelayed(r, 1000); 
+0

如果您希望计时器准确无误,最好从可运行内部发布消息,而不是直接更新UI。当然,理想的情况是,您应该像上面提到的那样在服务中安装计时器。 – rajath 2011-03-26 08:17:56

+0

我发现postDelayed发射的时间差异很大。当屏幕*关闭* 2分钟设置会导致6 - 14分钟的延迟。 (Android 2.2,HTC Hero) – fadedbee 2012-06-12 13:25:18

回答

2

你的代码是有点儿八九不离十设计是不准确的,因为你不占由可运行的胆量所花费的时间。你可能会通过做类似

public void run(){ 
    startTime = System.currentTimeMillis(); 
    // compare expectedTime to startTime and compensate 
    // <guts of runnable goes here> 
    // now wrap it up... 
     delay = 1000 - (System.currentTimeMillis() - startTime); 
    if (delay < 0) 
     delay = 0; 
    expectedTime = System.currentTimeMillies() + delay; 
    handler.postDelayed(this, delay); 
} 
+0

我考虑过这种方法。按时完成倒计时,但延迟校正导致定时器在需要延迟校正时不显示第二个。这种行为是不期望的,因为它给出了计时器不准确的外观。 – MikeU 2011-03-30 05:36:50

+0

@MikeU是的,的确如此:这种方法偶尔会跳过一拍。你的问题的答案是:postDelayed()的时间是*不*保证 - 它只是近似值。如果您需要更高的准确性,您确实需要尝试更复杂的方法。 – 2011-03-30 12:19:10

+0

@MikeU感谢您接受我的回答 - 让我再考虑一下您的问题:-)我编辑了我的回答,添加了一个可能有所帮助的附加功能:您可能需要设置一个变量来保存您的时间“预计”下一次回调发生,所以你可以检测并可能补偿古怪。我认为这是复杂性的下一步 - 可能有用但仍然可以管理。当然,您需要在构造函数中将expectedTime初始化为0,并在第一次调用runnable时忽略此值。祝你好运。 – 2011-04-17 15:44:18

1

怎么样使用CountDownTimer?我多次用它来完成相同的任务,并没有遇到这种问题。