Android Countdown error solution appears

Disclaimer: This article is a blogger original article, follow the CC 4.0 BY-SA copyright agreement, reproduced, please attach the original source link and this statement.
This link: https://blog.csdn.net/asd501823206/article/details/99704212

EDITORIAL

These days in the countdown to achieve a total and related functions, use CountDownTimer achieve. However, when testing found that the countdown is often found jumping seconds, 1 case does not appear, therefore in this regard had some understanding. This article is not ready to introduce the countdown to the exact reason CountDownTimer, and a timer of its own realization -


CountDownTimer problem

After the discovery of the leap second, Question 1 does not appear, first each onTick () callback time to print out (here forget to save the log, and then dictate it). We encountered a problem in the online search to, mostly because the interval to 1000ms, but the callback time every few milliseconds, or ten milliseconds per cent more, and my equipment in the actual test, more 40ms, i.e. every countdown 25s, will skip the display of one second.

First we look at CountDownTimer the source code is very simple, online analysis also grasping a lot, there is not much to say. Posted key components:

    synchronized (CountDownTimer.this) {
        if (mCancelled) {
            return;
        }

        final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime();

        if (millisLeft <= 0) {
            onFinish();
        } else {
           long lastTickStart = SystemClock.elapsedRealtime();
           onTick(millisLeft);

            // take into account user's onTick taking time to execute
            long lastTickDuration = SystemClock.elapsedRealtime() - lastTickStart;
            long delay;

            if (millisLeft < mCountdownInterval) {
                // just delay until done
                delay = millisLeft - lastTickDuration;

                // special case: user's onTick took more than interval to
                // complete, trigger onFinish without delay
                if (delay < 0) delay = 0;
            } else {
                delay = mCountdownInterval - lastTickDuration;

                // special case: user's onTick took more than interval to
                // complete, skip to next interval
                while (delay < 0) delay += mCountdownInterval;
            }

            sendMessageDelayed(obtainMessage(MSG), delay);
        }
    }

On the calculation of the code delay is the time before and after use to perform calculation onTick come, i.e., after the execution time delay onTick; sendMessageDelayed but does not guarantee accurate to a millisecond, including before and after onTick judgment, read data, this part time-consuming do not count. Because different models use different ways, resulting in different time delays.


Custom Countdown

Implementation and CountDownTimer, as implemented by Handler. Because business needs, directly make a second countdown peeled business logic, code stickers.

The main idea: to go into the calculation before sending the message to calculate the delay.

Calculated: the recording time lastMills (ms) at the start, after each transmitted message, lastMills increment 1000; obtain the current time before sending each message, a difference between the calculated and the expected arrival time of the next message, That message is transmitted this time delay

    class MyHandler extends Handler {
        private int totalSeconds;

        private long lastMills = 0L;


        MyHandler(int totalSeconds) {
            super();
            this.totalSeconds = totalSeconds;
        }

        public void start() {
            Message msg = obtainMessage();
            sendMessage(msg);
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);

            boolean isContinue = true;
            if (totalSeconds > 0) {
                // do sth when tick
            } else {
                isContinue = false;
            }

            if (isContinue) {
                totalSeconds --;
                long internal = 1000;
                long now = System.currentTimeMillis();
                // print time
                Log.i(TAG, "handleMessage: now=" + now);
                if (lastMills != 0L) {
                    internal = internal - (now - lastMills);
                    lastMills += 1000;
                } else {
                    lastMills = now + 1000;
                }

                Message message = obtainMessage();
                sendMessageDelayed(message, internal);
            } else {
                finish();
            }
        }

        private void finish() {
            // do things when finish
        }
    }

Print out each time, the error is within a few milliseconds fluctuations, and does not accumulate; If you are a whole number, rounding is preferably increased when using the fluctuating destroyed.

Johnny Deng : 08-18 13:32:47.894 handleMessage: now=1566106367894
Johnny Deng : 08-18 13:32:48.894 handleMessage: now=1566106368894
Johnny Deng : 08-18 13:32:49.894 handleMessage: now=1566106369894
Johnny Deng : 08-18 13:32:50.896 handleMessage: now=1566106370896
Johnny Deng : 08-18 13:32:51.895 handleMessage: now=1566106371895
Johnny Deng : 08-18 13:32:52.897 handleMessage: now=1566106372896
Johnny Deng : 08-18 13:32:53.896 handleMessage: now=1566106373896
Johnny Deng : 08-18 13:32:54.894 handleMessage: now=1566106374894
Johnny Deng : 08-18 13:32:55.896 handleMessage: now=1566106375896
Johnny Deng : 08-18 13:32:56.894 handleMessage: now=1566106376894
Johnny Deng : 08-18 13:32:57.895 handleMessage: now=1566106377895
Johnny Deng : 08-18 13:32:58.893 handleMessage: now=1566106378893
Johnny Deng : 08-18 13:32:59.881 handleMessage: now=1566106379881
Johnny Deng : 08-18 13:33:00.901 handleMessage: now=1566106380901
Johnny Deng : 08-18 13:33:01.893 handleMessage: now=1566106381893
Johnny Deng : 08-18 13:33:02.894 handleMessage: now=1566106382894
Johnny Deng : 08-18 13:33:03.895 handleMessage: now=1566106383895
Johnny Deng : 08-18 13:33:04.895 handleMessage: now=1566106384895
Johnny Deng : 08-18 13:33:05.895 handleMessage: now=1566106385894
Johnny Deng : 08-18 13:33:06.895 handleMessage: now=1566106386895
Johnny Deng : 08-18 13:33:07.894 handleMessage: now=1566106387894
Johnny Deng : 08-18 13:33:08.897 handleMessage: now=1566106388897
Johnny Deng : 08-18 13:33:09.897 handleMessage: now=1566106389897
Johnny Deng : 08-18 13:33:10.893 handleMessage: now=1566106390893
Johnny Deng : 08-18 13:33:11.893 handleMessage: now=1566106391893
Johnny Deng : 08-18 13:33:12.896 handleMessage: now=1566106392896
Johnny Deng : 08-18 13:33:13.895 handleMessage: now=1566106393895
Johnny Deng : 08-18 13:33:14.895 handleMessage: now=1566106394895
Johnny Deng : 08-18 13:33:15.894 handleMessage: now=1566106395894
Johnny Deng : 08-18 13:33:16.898 handleMessage: now=1566106396898

If you find any problem in this article, I hope you can point out that I make changes; if this article to help you have some trouble bigwigs to the point of a praise ~

Guess you like

Origin blog.csdn.net/asd501823206/article/details/99704212