我正在创建一个Android应用程序,在某些活动中显示一个小时分钟和秒钟的计时器。由于秒值将每秒更新一次,我正在考虑制作一个1000毫秒睡眠的线程,在每个周期后它将添加1到秒并更新文本视图。因此,它将计算分钟和小时并更新相应的文本视图。
但是我有一个疑问,线程是否足够可靠以完成这样的任务,还是应该使用内置的库函数来在每个周期后获得几秒钟?如果我完全依赖线程计算时间,我有点担心我的计时器不同步。
答案 0 :(得分:8)
睡眠不够好。
睡眠将暂停线程至少指定的时间段,但实际的睡眠时间可能比指定的时间长。
答案 1 :(得分:7)
long startTime = 0;
Handler timerHandler = new Handler();
Runnable timerRunnable = new Runnable() {
@Override
public void run() {
long millis = System.currentTimeMillis() - startTime;
int seconds = (int) Math.round(diff / ((double)1000));
int minutes = (int) Math.round(seconds / ((double)60));
seconds = seconds % 60;
// Use the seconds
timerHandler.postDelayed(this, 500);
}
};
启动计时器 -
startTime = System.currentTimeMillis();
timerHandler.postDelayed(timerRunnable, 0);
停止计时器 -
timerHandler.removeCallbacks(timerRunnable);
暂停 -
timerHandler.removeCallbacks(timerRunnable);
答案 2 :(得分:3)
延迟1000毫秒的睡眠是不好的选择,因为总是存在抖动,并且在执行例程时也会花费一些CPU时间。
我建议从ScheduledExecutorService.scheduleAtFixedRate方法中获利,这将以固定费率调用您的实施。
答案 3 :(得分:2)
根据您所描述的逻辑,您确实会得到一些漂移,即每个周期可能会产生的小错误将会增加很多。虽然很容易补救。
保持变量保持最后一次触发的时间。完成睡眠后,将1000
添加到最后一个触发时间,计算剩余时间直到该时间,然后再睡眠。通过这种方式,您可能偶尔会遇到延迟触发,但很快就会得到纠正。
答案 4 :(得分:2)
永远不应该依赖线程sleep
。它不保证确切的时差。
我建议您使用计时器任务。它易于使用且非常可靠。
祝你好运。答案 5 :(得分:1)
但我心中有一个疑问,线程是否足够可靠 完成这样的任务
不,他们不是。
您可以使用线程更新时钟显示,但您应该再次阅读System.currentTimeMillis()(或类似)。
答案 6 :(得分:1)
如果您说睡眠1秒钟,线程将休眠1秒钟,线程唤醒时指令发生的实际时间取决于其他因素,例如操作系统和CPU的线程调度。它不大可能产生巨大的影响,但为什么不简单地跟踪实际的时间戳,以便确切地知道已经过了多少时间,并且如果有任何差异则相应地更正?
这样简单的内容答案 7 :(得分:1)
在android中使用sleep的简单线程是不可能的。只需使用runnable thread。
当您需要根据秒数更新textview时启动此功能。在这个我尝试了分钟,秒和毫秒。
看看吧。
创建一个textview,并使用以下runnable设置文本。
private Runnable updateTimerThread = new Runnable() {
public void run() {
timeInMilliseconds = SystemClock.uptimeMillis() - startTime;
updatedTime = timeSwapBuff + timeInMilliseconds;
int secs = (int) (updatedTime / 1000);
int mins = secs / 60;
secs = secs % 60;
int milliseconds = (int) (updatedTime % 1000);
t1.setText("" + mins + ":"
+ String.format("%02d", secs) + ":"
+ String.format("%03d", milliseconds));
customHandler.postDelayed(this, 0);
}
};
答案 8 :(得分:1)
正如其他人所指出的那样,sleep(millis)
只保证至少的睡眠时间为毫秒 - 这意味着如果你使用1000
而不是偏移它将是落后了。
与偏移量一起使用:
long last = System.currentTimeMillis();
while (true) {
long current = System.currentTimeMillis();
Thread.sleep(last-current);
last = current;
incrementSeconds();
}