44

我有一个 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();

现在我需要两件事:

  • 一种如何计算经过时间并将其存储在变量中的方法
  • 我需要最终值是双倍的,例如最终得分是:15.49 秒。
4

5 回答 5

84

游戏开始时:

long tStart = System.currentTimeMillis();

游戏结束时:

long tEnd = System.currentTimeMillis();
long tDelta = tEnd - tStart;
double elapsedSeconds = tDelta / 1000.0;
于 2013-03-06T13:41:14.853 回答
62

根据 Android文档 SystemClock.elapsedRealtime()是通用间隔计时的推荐基础。这是因为,根据文档, elapsedRealtime()is guaranteed to be monotonic, [...], so is the recommend basis for general purpose interval timing.

SystemClock文档很好地概述了各种时间方法及其适用的用例。

  • 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(...)

此外,Timer您可能想研究 using ,而不是 using TimerTask,这个类是为您想要做的事情而设计的。唯一的问题是它倒计时而不是倒计时,但这可以通过简单的减法来解决。

于 2013-09-01T03:12:28.607 回答
12

甚至更好!

long tStart = System.nanoTime();
long tEnd = System.nanoTime();
long tRes = tEnd - tStart; // time in nanoseconds

阅读有关 nanoTime()的文档!

于 2014-07-24T00:27:09.340 回答
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);
    }
}
于 2019-05-22T08:17:15.457 回答
1

从 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));
于 2019-12-26T08:51:51.440 回答