为什么倒计时器与线程显示错误值?

时间:2015-04-23 06:04:40

标签: android multithreading

我不知道为什么这个倒数计数器在结尾显示一个随机数? 我的意思是它有时显示60:15,有时是60:07,所以就这样

min=sec=0;
new Thread(new Runnable() {
    @Override
    public void run() {
        while (min < 60  && flagTime) {
            try {
                Thread.sleep(1);
                G.HANDLER.post(new Runnable() {
                    @Override
                    public void run() {
                        String preSec="";
                        String preMin="";
                        if (sec < 59) {
                            sec += 1;
                        }
                        if (sec < 10) {
                            preSec = "0";
                        } 
                        if (min < 10) {
                            preMin = "0";
                        }
                        score =preMin + min + ":"
                                + preSec + sec;
                        txt[elementNumber + 1].setText(score);
                    }
                });
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}).start();

请有人告诉我为什么它的工作如此奇怪?

2 个答案:

答案 0 :(得分:1)

所有操作系统中的时间安排都不准确,除非您使用已为此任务设计的框架或工具。但是,您可以使用具有合理不确定性的Thread.Sleep。但是对于&#34;合理的&#34;并且&#34;精确&#34;时间,这取决于你试图解决的问题。

在线程中,sleep(1000)并不意味着线程将在1秒内完全睡眠,因此每次运行应用程序时线程将睡眠更少或更多。这就是你得到随机结果的原因。

除了线程的优先级之外,还有许多其他事情需要考虑。 所以更好的倒计时方法是使用android提供的其他方法:

CountDownTimer

Timer

您可以查看谷歌,你会发现很多关于如何使用它们的例子。

那些更可靠,更强精确

希望这会有所帮助。

答案 1 :(得分:0)

您在TextView中获得奇怪结果的可能原因是您正在从不是主UI线程的线程中更新它。

但是你要比现在更难。一种更简单的方法是使用这样的简单CountDownTimer对象:

final long SECS_IN_1_MIN = 60;
final long MILLIS_IN_1_SEC = 1000;
final long MILLIS_IN_60_MINS = 3600000;

final TextView timer = (TextView) findViewById(R.id.timer);
new CountDownTimer(MILLIS_IN_60_MINS, MILLIS_IN_1_SEC) {
    public void onTick(long millisUntilFinished) {
        if (flagTime) {
            long secs = (MILLIS_IN_60_MINS - millisUntilFinished) / MILLIS_IN_1_SEC;
            timer.setText(String.format("%02d:%02d", secs / SECS_IN_1_MIN, secs % SECS_IN_1_MIN));

        } else {
            timer.setText("cancelled");
            cancel();
        }
    }

    public void onFinish() {
        timer.setText("time expired");
    }
}.start();

编辑:它使用CountDownTimer来处理时间,同时使用其millisUntilFinished值来计算和显示看起来越来越多的秒数。我投入了一些符号名称以使代码更清晰,并使用String.format以更优雅的方式处理单个数字值。享受!