将自定义计时器同步到系统时钟时出现问题

时间:2019-04-07 20:14:05

标签: java android timer

我有一个自定义计时器,可以与系统时钟保持同步。可以在一分钟的间隔内正常工作,但我还需要将其同步到36秒的间隔(用于在用户希望以十进制小时显示时间时更新字段)。在Runnable内部,我会在下一分钟重新计算调整(足够精确以满足我的需要),但是找不到一种方法来方便地处理36秒所需的不同偏移量。

编辑

    private static class DecimalTimer extends TimerClass {

        final int[] seconds = new int[101];
        private boolean keepRunning = true;
        private Runnable mRunnable;

        @Override
        void kill() {
            keepRunning = false;
        }

        @Override
        Runnable getRunnable() {
            return mRunnable;
        }

        DecimalTimer() {
            final int[] counter = new int[1];
            for (int i = 0, j = 0; i < 3600; i += 36, j++) {
                seconds[j] = i;
            }
            mRunnable = new Runnable() {
                @Override
                public void run() {
                    if (!keepRunning)
                        return;
                    final Calendar c = Calendar.getInstance();
                    int hourSeconds = c.get(Calendar.MINUTE) * 60 + c.get(Calendar.SECOND);

                    for (counter[0] = 0; counter[0] < 100; counter[0]++) {
                        if (seconds[counter[0]] > hourSeconds) {
                            c.add(Calendar.SECOND, seconds[counter[0]]);
                            break;
                        }
                    }
                    long adjustedDelay = (c.getTimeInMillis() - System.currentTimeMillis()) % 36000;

                    for (IntervalTimer listener : sListeners) {
                        listener.updateTime();
                    }
                    sHandler.postDelayed(this, adjustedDelay);
                }
            };


        }
    }

此编辑每36秒触发一次,但我需要使其同步到时钟上的36秒(即:12:00:00,然后12:00:36 .. 12:01:12 .. 12: 01:48)

1 个答案:

答案 0 :(得分:0)

像往常一样仔细思考,这就是我想出的。它可以满足我的需求,但如果有人对精度有所改进(以900ms或更长的时间执行时会有些许偏离),将不胜感激。

        DecimalTimer() {
            mRunnable = new Runnable() {
                @Override
                public void run() {
                    if (!keepRunning)
                        return;

                    final Calendar c = Calendar.getInstance();
                    c.set(Calendar.MINUTE, 0);
                    c.set(Calendar.SECOND, 0);
                    do {
                        c.add(Calendar.SECOND, 36);
                    } while (c.getTimeInMillis() < System.currentTimeMillis());
                    long adjustedDelay = (c.getTimeInMillis() - System.currentTimeMillis()) % 36000;

                    for (IntervalTimer listener : sListeners) {
                        listener.updateTime();
                    }
                    sHandler.postDelayed(this, adjustedDelay);
                }
            };
        }