android countdowntimer tick不准确 [英] android countdowntimer tick is not accurate

查看:125
本文介绍了android countdowntimer tick不准确的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用倒数计时器进行音频通知......从一开始就不准确...



使用初始参数

  private final long startCountDown; 
private final long intervalCountDown;
...
startCountDown = 180 * 1000; // 3分钟 - 稍后从偏好设置
intervalCountDown = 60 * 1000; // 1个MNS - 从个人偏好进行设置后
...
公共无效onTick(长millisUntilFinished){
Log.d(TAG, 通知倒计时: + millisUntilFinished +毫秒);
}


countDownTimer = new SwimCountDownTimer(startCountDown,intervalCountDown);
....

public void startCountDown(){
Log.d(TAG,start countDown for+ startCountDown +msecs);
countDownTimer.start();
}

我可以在日志中看到初始倒计时正确设置为180000但是下一个应该是120000,它设置为119945 !!!

  04-27 14:50:42.146:I / SWIMMER (8670):通知倒计时:180000毫秒
04-27 14:51:42.206:I / SWIMMER(8670):通知倒计时:119945毫秒

这很烦人,因为音频通知器只能说2分钟而不是1分59秒...;为什么间隔不对...?
我可以设置自己的文本到语音字符串...但有没有办法获得正确的数据?



谢谢你建议

解决方案

我知道这是一个老问题 - 但我也遇到了这个问题,并认为我会分享我的解决方案。



显然CountDownTimer不是很准确,所以我决定实施一个更精确的倒数计时器,usi ng java.util.Timer:

  public abstract class PreciseCountdown extends Timer {
private long totalTime,interval,delay;
私有TimerTask任务;
private long startTime = -1;
private boolean restart = false,wasCancelled = false,wasStarted = false;

public PreciseCountdown(long totalTime,long interval){
this(totalTime,interval,0);
}

public PreciseCountdown(long totalTime,long interval,long delay){
super(PreciseCountdown,true);
this.delay = delay;
this.interval = interval;
this.totalTime = totalTime;
this.task = getTask(totalTime);
}

public void start(){
wasStarted = true;
this.scheduleAtFixedRate(任务,延迟,间隔);
}

public void restart(){
if(!wasStarted){
start();
}
else if(wasCancelled){
wasCancelled = false;
this.task = getTask(totalTime);
start();
}
else {
this.restart = true;
}
}

public void stop(){
this.wasCancelled = true;
this.task.cancel();
}

//当此计时器没有进一步使用时调用此方法
public void dispose(){
cancel();
purge();
}

private TimerTask getTask(final long totalTime){
return new TimerTask(){

@Override
public void run( ){
long timeLeft;
if(startTime< 0 || restart){
startTime = scheduledExecutionTime();
timeLeft = totalTime;
restart = false;
} else {
timeLeft = totalTime - (scheduledExecutionTime() - startTime);

if(timeLeft< = 0){
this.cancel();
startTime = -1;
onFinished();
返回;
}
}

onTick(timeLeft);
}
};
}

public abstract void onTick(long timeLeft);
public abstract void onFinished();
}

用法示例如下:



'pre> this.countDown =新PreciseCountdown(TOTALTIME,间隔,延迟){
@覆盖
公共无效onTick(长的timeleft){
/ / update ..
//请注意,这是在不同的线程上运行,所以更新任何需要使用的GUI组件Activity.runOnUiThread()
}

@Override
public void onFinished(){
onTick(0); //当计时器结束时onTick不被称为
//倒计时结束
}
};

开始倒计时,只需调用countDown.start()。
countDown.stop()停止countDown,可以使用countDown.restart()重新启动。



希望这对将来的任何人都有帮助。


I am using a countdown timer for audio notification... and it's not accurate from the start...

using initial parameters

private final long startCountDown; 
private final long intervalCountDown;
    ...
    startCountDown = 180 * 1000;   // 3 mns  - to be set from Preferences later
intervalCountDown = 60 * 1000;   // 1 mns - to be set from Preferences later
    ...
    public void onTick(long millisUntilFinished) {
       Log.d(TAG, "notify countDown: " + millisUntilFinished + " msecs");
    }


    countDownTimer = new SwimCountDownTimer(startCountDown,intervalCountDown);
    ....

public void startCountDown() {
    Log.d(TAG, "start countDown for " + startCountDown + " msecs" );
    countDownTimer.start();
}

I can see in the log that the initial countdown is correctly set to 180000 but the next one should be 120000 and it's set to 119945 !!!

04-27 14:50:42.146: I/SWIMMER(8670): notify countDown: 180000 msecs
04-27 14:51:42.206: I/SWIMMER(8670): notify countDown: 119945 msecs

This is quite annoying as the audio notifier is expecting to say only '2 minutes" and not "1 minute and fifty nine seconds" ...; why the interval is not right ... ? I can tricj it in setting myself the text to speech string ... but is there any way to get correct data ?

thanks for suggestions

解决方案

I know it's an old question- but I've also encountered the problem, and thought I would share my solution.

Apperantly CountDownTimer isn't very accurate, so I've decided to implement a more percise countdown timer, using java.util.Timer:

public abstract class PreciseCountdown extends Timer {
    private long totalTime, interval, delay;
    private TimerTask task;
    private long startTime = -1;
    private boolean restart = false, wasCancelled = false, wasStarted = false;

    public PreciseCountdown(long totalTime, long interval) {
        this(totalTime, interval, 0);
    }

    public PreciseCountdown(long totalTime, long interval, long delay) {
        super("PreciseCountdown", true);
        this.delay = delay;
        this.interval = interval;
        this.totalTime = totalTime;
        this.task = getTask(totalTime);
    }

    public void start() {
        wasStarted = true;
        this.scheduleAtFixedRate(task, delay, interval);
    }

    public void restart() {
        if(!wasStarted) {
            start();
        }
        else if(wasCancelled) {
            wasCancelled = false;
            this.task = getTask(totalTime);
            start();
        }
        else{
            this.restart = true;
        }
    }

    public void stop() {
        this.wasCancelled = true;
        this.task.cancel();
    }

    // Call this when there's no further use for this timer
    public void dispose(){
        cancel();
        purge();
    }

    private TimerTask getTask(final long totalTime) {
        return new TimerTask() {

            @Override
            public void run() {
                long timeLeft;
                if (startTime < 0 || restart) {
                    startTime = scheduledExecutionTime();
                    timeLeft = totalTime;
                    restart = false;
                } else {
                    timeLeft = totalTime - (scheduledExecutionTime() - startTime);

                    if (timeLeft <= 0) {
                        this.cancel();
                        startTime = -1;
                        onFinished();
                        return;
                    }
                }

                onTick(timeLeft);
            }
        };
    }

    public abstract void onTick(long timeLeft);
    public abstract void onFinished();
}

Usage example would be:

this.countDown = new PreciseCountdown(totalTime, interval, delay) {
    @Override
    public void onTick(long timeLeft) {
        // update..
        // note that this runs on a different thread, so to update any GUI components you need to use Activity.runOnUiThread()
    }

    @Override
    public void onFinished() {
        onTick(0); // when the timer finishes onTick isn't called
        // count down is finished
    }
};

to start the countdown, simply call countDown.start(). countDown.stop() stops the countDown, which could be restarted using countDown.restart().

Hope this is any help for anyone in the future.

这篇关于android countdowntimer tick不准确的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆