Stop using TIME_TICK broadcast in TextClock

This gets called even when the view is not visible, which is bad for
performance. I've adapted the existing tick framework to handle ticking
for minutes when there aren't seconds in the format.

I verified the correct behavior with sample apps with and without
seconds in the format, including across DST time changes.

Fix: 190467448
Test: locally with sample apps
Change-Id: I75fed5c9d162b5361c31fe22d057a007db0ce75c
This commit is contained in:
Stevie Kideckel
2021-06-08 11:14:38 +00:00
parent ebcaa39d6b
commit 95b804ad4f

View File

@@ -34,7 +34,6 @@ import android.icu.text.DateTimePatternGenerator;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.Settings;
import android.text.format.DateFormat;
@@ -45,6 +44,10 @@ import android.view.inspector.InspectableProperty;
import com.android.internal.R;
import java.time.Duration;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Calendar;
import java.util.TimeZone;
@@ -185,18 +188,29 @@ public class TextClock extends TextView {
private final Runnable mTicker = new Runnable() {
public void run() {
if (mStopTicking) {
removeCallbacks(this);
if (mStopTicking || !mShouldRunTicker) {
return; // Test disabled the clock ticks
}
onTimeChanged();
long now = SystemClock.uptimeMillis();
long next = now + (1000 - now % 1000);
Instant now = mTime.toInstant();
ZoneId zone = mTime.getTimeZone().toZoneId();
Handler handler = getHandler();
if (handler != null) {
handler.postAtTime(mTicker, next);
ZonedDateTime nextTick;
if (mHasSeconds) {
nextTick = now.atZone(zone).plusSeconds(1).withNano(0);
} else {
nextTick = now.atZone(zone).plusMinutes(1).withSecond(0).withNano(0);
}
long millisUntilNextTick = Duration.between(now, nextTick.toInstant()).toMillis();
if (millisUntilNextTick <= 0) {
// This should never happen, but if it does, then tick again in a second.
millisUntilNextTick = 1000;
}
postDelayed(this, millisUntilNextTick);
}
};
@@ -519,8 +533,7 @@ public class TextClock extends TextView {
mHasSeconds = DateFormat.hasSeconds(mFormat);
if (mShouldRunTicker && hadSeconds != mHasSeconds) {
if (hadSeconds) getHandler().removeCallbacks(mTicker);
else mTicker.run();
mTicker.run();
}
}
@@ -557,14 +570,10 @@ public class TextClock extends TextView {
if (!mShouldRunTicker && isVisible) {
mShouldRunTicker = true;
if (mHasSeconds) {
mTicker.run();
} else {
onTimeChanged();
}
mTicker.run();
} else if (mShouldRunTicker && !isVisible) {
mShouldRunTicker = false;
getHandler().removeCallbacks(mTicker);
removeCallbacks(mTicker);
}
}
@@ -592,7 +601,6 @@ public class TextClock extends TextView {
private void registerReceiver() {
final IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_TIME_TICK);
filter.addAction(Intent.ACTION_TIME_CHANGED);
filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);