【问题标题】:Accurate countdown?准确的倒计时?
【发布时间】:2016-02-09 04:19:36
【问题描述】:

我想看看用户是否在一秒钟内完成了某个任务。我知道有几种方法可以让时间流逝,但我想知道这种情况下最准确的方法是什么。我想从某个时间开始流逝。比如注册一个定时器,稍后再参考:

  1. 用户做某事

  2. 我检查用户是否在一秒内完成任务

  3. 用户又做了某事

  4. 我检查用户是否在之前运行的同一个一秒计时器内完成了任务。如果没有,请将计时器设为空。

  5. 用户又做了某事

  6. 我检查用户是否在一秒内完成了任务。如果没有,请将计时器设为空。

当用户完成各种任务时,我希望基本上有一个运行一秒钟的计时器。每完成一项任务后,我都会检查计时器是否仍在运行。我不想为此使用倒数计时器,因为它在一秒钟内不够准确。我可以使用什么方法?

【问题讨论】:

    标签: java android performance oop optimization


    【解决方案1】:

    如果您需要纳秒级精度,请使用 System.currentTimeMillis()System.nanoTime()。我想,System.currentTimeMillis() 的精度应该足以满足您的情况。

    在开始一项任务之前记录一个时间戳,然后在刚刚完成一项任务和任务之后记录一个时间戳。

    查看this answer 了解哪种方法更适合您。

    【讨论】:

    • 我已经尝试过了,但我的问题是我在一个单独的类中的侦听器中执行所有这些操作。每当它再次开始收听时,我之前记录的时间戳变量就会被删除,并且当我尝试使用它时会得到空值。如何防止此变量(双精度)丢失其数据?
    【解决方案2】:

    如果您想要最高精度,请使用System.nanoTime()。 System.currentTimeMillis() 应该也适合你。

    此方法提供纳秒精度,但不一定提供纳秒分辨率(即值更改的频率) - 不保证分辨率至少与 currentTimeMillis() 一样好。

    只需使用这两种方法中的任何一种来实现一个简单的计时器。

    private static final class Timer {
    
        private long start;
        private long end;
    
        static double toSeconds(long nanos) {
            return nanos / 1000000000.0;
        }
    
        void start() {
            end = -1;
            start = System.nanoTime();
        }
    
        double getCurrent() {
            return toSeconds(System.nanoTime() - start);
        }
    
        double stop() {
            end = System.nanoTime();
            return toSeconds(end - start); 
        }
    
        boolean isRunning() {
            return end == -1;
        }
    
    }
    
    public static void main(String[] args) {
        Timer timer = new Timer();
    
        timer.start();
        doSomething();
        if (timer.getCurrent() > 1.0) {
            double time = timer.stop();
            System.out.println("User completed task 1 in " + time);
        }
    
        doSomething();
        if (timer.isRunning() && timer.getCurrent() > 1.0) {
            double time = timer.stop();
            System.out.println("User completed task 1 & 2 in " + time);
        }
    
        doSomething();
        if (timer.isRunning() && timer.getCurrent() > 1.0) {
            double time = timer.stop();
            System.out.println("User completed task 1 & 2 & 3 in " + time);
        }
    
        System.out.println("All tasks finished");
    
    }
    

    【讨论】:

    • 我已经尝试过了,但我的问题是我一直在在一个单独的类中的监听器中进行录制。每当它再次开始收听时,我之前记录的时间戳变量就会被删除,并且当我尝试使用它时会得到空值。如何防止此变量(双精度)丢失其数据?
    • 不知道代码的情况下有点难说。也许你可以检查它是否已经在记录时间?
    • 取决于你的代码;也许你可以更新问题?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-13
    • 2020-03-23
    • 2020-12-17
    • 2020-11-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多