Why is the flow countdown counter showing the wrong value?

I don't know why this countdown counter shows a random number at the end?
I mean sometimes it shows 60:15, sometimes 60:07, so along the way

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();

      

Please tell me why does this work so strange?

+3


source to share


2 answers


Timing in all operating systems is not accurate unless you use a framework or tools that are already developed for the task. However, you can work with Thread.Sleep with reasonable uncertainty. But for "reasonable" and "accurate" times, it depends on the problem you are trying to solve.

In threads, sleep (1000) does not mean that the thread will sleep for exactly 1 second, so the thread will sleep less or more each time the application starts. so you get random results.

It has many things to consider as a thread priority. so the best way to count is to use other ways that android provides:

CountDownTimer



Timer

you can check google and you will find many examples on how to use them.

they are more reliable and more accurate .

hope this helps.

+1


source


The likely reason you are getting strange results in the TextView is because you are updating it from a thread that is not the main UI thread.

But you're making it harder than it should be. An easier approach is to use a simple CountDownTimer object like this:



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();

      

Change: . It uses CountDownTimer to handle the time, using the value millisUntilFinished

to calculate and display what appears to increase as the number of seconds increases. I've added some symbolic names to make the code clearer and String.format to handle unambiguous values ​​more clearly. Enjoy!

0


source







All Articles