我有一个10和20的问题游戏。我需要计算用户完成游戏后经过的时间。
Timer T=new Timer();
T.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable()
{
public void run()
{
countdown.setText(""+count);
count++;
}
});
}
}, 1000, 1000);
我用这个来阻止计数器:
T.cancel();
现在我需要两件事:
答案 0 :(得分:72)
游戏开始时:
long tStart = System.currentTimeMillis();
游戏结束时:
long tEnd = System.currentTimeMillis();
long tDelta = tEnd - tStart;
double elapsedSeconds = tDelta / 1000.0;
答案 1 :(得分:48)
根据Android docs SystemClock.elapsedRealtime()
是通用间隔时间的推荐基础。这是因为根据文档,elapsedRealtime()is guaranteed to be monotonic, [...], so is the recommend basis for general purpose interval timing.
SystemClock documentation概述了各种时间方法及其适用的用例。
SystemClock.elapsedRealtime()
和SystemClock.elapsedRealtimeNanos()
是计算通用时间的最佳选择。SystemClock.uptimeMillis()
和System.nanoTime()
是另一种可能性,但与推荐的方法不同,它们不包括深度睡眠时间。如果这是你想要的行为,那么他们可以使用。否则坚持使用elapsedRealtime()
。System.currentTimeMillis()
,因为这将返回“挂墙”时钟时间。由于挂钟时间可能向前或向后跳跃,因此不适合计算经过时间。像NTP客户端这样的很多东西都会导致挂钟时间跳跃和歪斜。这将导致基于currentTimeMillis()
的经过时间计算并不总是准确的。游戏开始时:
long startTime = SystemClock.elapsedRealtime();
游戏结束时:
long endTime = SystemClock.elapsedRealtime();
long elapsedMilliSeconds = endTime - startTime;
double elapsedSeconds = elapsedMilliSeconds / 1000.0;
此外,Timer()是尽力而为计时器,并不总是准确的。因此在游戏持续时间内会有累积的计时错误。要更准确地显示过渡时间,请定期检查System.currentTimeMillis()
作为发送到setText(...)
的时间的基础。
此外,您可能希望使用TimerTask
来代替使用Timer
,而是针对您要执行的操作而设计此类。唯一的问题是它倒计时而不是向上,但这可以通过简单的减法来解决。
答案 2 :(得分:10)
更好!
long tStart = System.nanoTime();
long tEnd = System.nanoTime();
long tRes = tEnd - tStart; // time in nanoseconds
阅读关于nanoTime()的documentation!
答案 3 :(得分:1)
有许多方法可以实现这一点,但是测量经过时间的最重要考虑因素是使用System.nanoTime()
和TimeUnit.NANOSECONDS
作为时间单位。 我为什么要这样做?好吧,这是因为System.nanoTime()
方法返回了高分辨率的时间源,距离某个参考点(即Java虚拟机的启动)以纳秒为单位。
此方法只能用于测量经过时间,与系统或挂钟时间的任何其他概念无关。
出于相同的原因,建议避免使用System.currentTimeMillis()
方法来测量经过时间。此方法返回wall-clock
时间,该时间可能会因许多因素而改变。这对您的测量结果不利。
请注意,虽然返回值的时间单位为毫秒,但值的粒度取决于基础操作系统,并且可能更大。例如,许多操作系统都以几十毫秒为单位测量时间。
因此,这里有一个基于System.nanoTime()
方法的解决方案,另一种使用Guava的解决方案,最后一个是Apache Commons Lang
public class TimeBenchUtil
{
public static void main(String[] args) throws InterruptedException
{
stopWatch();
stopWatchGuava();
stopWatchApacheCommons();
}
public static void stopWatch() throws InterruptedException
{
long endTime, timeElapsed, startTime = System.nanoTime();
/* ... the code being measured starts ... */
// sleep for 5 seconds
TimeUnit.SECONDS.sleep(5);
/* ... the code being measured ends ... */
endTime = System.nanoTime();
// get difference of two nanoTime values
timeElapsed = endTime - startTime;
System.out.println("Execution time in nanoseconds : " + timeElapsed);
}
public static void stopWatchGuava() throws InterruptedException
{
// Creates and starts a new stopwatch
Stopwatch stopwatch = Stopwatch.createStarted();
/* ... the code being measured starts ... */
// sleep for 5 seconds
TimeUnit.SECONDS.sleep(5);
/* ... the code being measured ends ... */
stopwatch.stop(); // optional
// get elapsed time, expressed in milliseconds
long timeElapsed = stopwatch.elapsed(TimeUnit.NANOSECONDS);
System.out.println("Execution time in nanoseconds : " + timeElapsed);
}
public static void stopWatchApacheCommons() throws InterruptedException
{
StopWatch stopwatch = new StopWatch();
stopwatch.start();
/* ... the code being measured starts ... */
// sleep for 5 seconds
TimeUnit.SECONDS.sleep(5);
/* ... the code being measured ends ... */
stopwatch.stop(); // Optional
long timeElapsed = stopwatch.getNanoTime();
System.out.println("Execution time in nanoseconds : " + timeElapsed);
}
}
答案 4 :(得分:0)
从Java 8开始,您可以尝试以下操作:
import java.time.*;
import java.time.temporal.ChronoUnit;
Instant start_time = Instant.now();
// Your code
Instant stop_time = Instant.now();
System.out.println(Duration.between(start_time, stop_time).toMillis());
//or
System.out.println(ChronoUnit.MILLIS.between(start_time, stop_time));