CountDownTimer: not skip onTick()

CoundDownTimer internally performs counting down with a handler and
fires onTick() callback at countdown intervals. At this internal
counting down, firing onTick() is skipped if the account of time until
finished is less than countdown interval. Due to this skip of onTick(),
user will miss last onTick() callback.

This change ensures CountDownTimer to fires every onTick() callback
until the time is up.

Bug: 32392931
Change-Id: I951f5cd46743873d7f8c353f8cf8c700999d8ae0
This commit is contained in:
Hidenari Koshimae
2016-10-18 20:43:16 +09:00
parent ff5c3ad08b
commit 0c3149191f

View File

@@ -125,19 +125,28 @@ public abstract class CountDownTimer {
if (millisLeft <= 0) {
onFinish();
} else if (millisLeft < mCountdownInterval) {
// no tick, just delay until done
sendMessageDelayed(obtainMessage(MSG), millisLeft);
} else {
long lastTickStart = SystemClock.elapsedRealtime();
onTick(millisLeft);
// take into account user's onTick taking time to execute
long delay = lastTickStart + mCountdownInterval - SystemClock.elapsedRealtime();
long lastTickDuration = SystemClock.elapsedRealtime() - lastTickStart;
long delay;
// special case: user's onTick took more than interval to
// complete, skip to next interval
while (delay < 0) delay += mCountdownInterval;
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);
}