am 61effdd2: am e5a6f821: Merge "Don\'t register more receivers and observers for every DateTimeView" into lmp-mr1-dev

* commit '61effdd2c2c945504fd788ee0dce5ccc5d57e66b':
  Don't register more receivers and observers for every DateTimeView
This commit is contained in:
Adam Powell
2014-11-09 19:27:31 +00:00
committed by Android Git Automerger

View File

@@ -32,6 +32,7 @@ import android.widget.RemoteViews.RemoteView;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date; import java.util.Date;
// //
@@ -62,8 +63,8 @@ public class DateTimeView extends TextView {
int mLastDisplay = -1; int mLastDisplay = -1;
DateFormat mLastFormat; DateFormat mLastFormat;
private boolean mAttachedToWindow;
private long mUpdateTimeMillis; private long mUpdateTimeMillis;
private static final ThreadLocal<ReceiverInfo> sReceiverInfo = new ThreadLocal<ReceiverInfo>();
public DateTimeView(Context context) { public DateTimeView(Context context) {
super(context); super(context);
@@ -76,15 +77,21 @@ public class DateTimeView extends TextView {
@Override @Override
protected void onAttachedToWindow() { protected void onAttachedToWindow() {
super.onAttachedToWindow(); super.onAttachedToWindow();
registerReceivers(); ReceiverInfo ri = sReceiverInfo.get();
mAttachedToWindow = true; if (ri == null) {
ri = new ReceiverInfo();
sReceiverInfo.set(ri);
}
ri.addView(this);
} }
@Override @Override
protected void onDetachedFromWindow() { protected void onDetachedFromWindow() {
super.onDetachedFromWindow(); super.onDetachedFromWindow();
unregisterReceivers(); final ReceiverInfo ri = sReceiverInfo.get();
mAttachedToWindow = false; if (ri != null) {
ri.removeView(this);
}
} }
@android.view.RemotableViewMethod @android.view.RemotableViewMethod
@@ -204,32 +211,19 @@ public class DateTimeView extends TextView {
} }
} }
private void registerReceivers() { void clearFormatAndUpdate() {
Context context = getContext(); mLastFormat = null;
update();
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_TIME_TICK);
filter.addAction(Intent.ACTION_TIME_CHANGED);
filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
context.registerReceiver(mBroadcastReceiver, filter);
Uri uri = Settings.System.getUriFor(Settings.System.DATE_FORMAT);
context.getContentResolver().registerContentObserver(uri, true, mContentObserver);
} }
private void unregisterReceivers() { private static class ReceiverInfo {
Context context = getContext(); private final ArrayList<DateTimeView> mAttachedViews = new ArrayList<DateTimeView>();
context.unregisterReceiver(mBroadcastReceiver); private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
context.getContentResolver().unregisterContentObserver(mContentObserver);
}
private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
String action = intent.getAction(); String action = intent.getAction();
if (Intent.ACTION_TIME_TICK.equals(action)) { if (Intent.ACTION_TIME_TICK.equals(action)) {
if (System.currentTimeMillis() < mUpdateTimeMillis) { if (System.currentTimeMillis() < getSoonestUpdateTime()) {
// The update() function takes a few milliseconds to run because of // The update() function takes a few milliseconds to run because of
// all of the time conversions it needs to do, so we can't do that // all of the time conversions it needs to do, so we can't do that
// every minute. // every minute.
@@ -237,16 +231,66 @@ public class DateTimeView extends TextView {
} }
} }
// ACTION_TIME_CHANGED can also signal a change of 12/24 hr. format. // ACTION_TIME_CHANGED can also signal a change of 12/24 hr. format.
mLastFormat = null; updateAll();
update();
} }
}; };
private ContentObserver mContentObserver = new ContentObserver(new Handler()) { private final ContentObserver mObserver = new ContentObserver(new Handler()) {
@Override @Override
public void onChange(boolean selfChange) { public void onChange(boolean selfChange) {
mLastFormat = null; updateAll();
update();
} }
}; };
public void addView(DateTimeView v) {
final boolean register = mAttachedViews.isEmpty();
mAttachedViews.add(v);
if (register) {
register(v.getContext().getApplicationContext());
}
}
public void removeView(DateTimeView v) {
mAttachedViews.remove(v);
if (mAttachedViews.isEmpty()) {
unregister(v.getContext().getApplicationContext());
}
}
void updateAll() {
final int count = mAttachedViews.size();
for (int i = 0; i < count; i++) {
mAttachedViews.get(i).clearFormatAndUpdate();
}
}
long getSoonestUpdateTime() {
long result = Long.MAX_VALUE;
final int count = mAttachedViews.size();
for (int i = 0; i < count; i++) {
final long time = mAttachedViews.get(i).mUpdateTimeMillis;
if (time < result) {
result = time;
}
}
return result;
}
void register(Context context) {
final IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_TIME_TICK);
filter.addAction(Intent.ACTION_TIME_CHANGED);
filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
context.registerReceiver(mReceiver, filter);
final Uri uri = Settings.System.getUriFor(Settings.System.DATE_FORMAT);
context.getContentResolver().registerContentObserver(uri, true, mObserver);
}
void unregister(Context context) {
context.unregisterReceiver(mReceiver);
context.getContentResolver().unregisterContentObserver(mObserver);
}
}
} }