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

* commit 'e5a6f821399bf354520f08f77819af4a846ae5f1':
  Don't register more receivers and observers for every DateTimeView
This commit is contained in:
Adam Powell
2014-11-09 19:23:04 +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.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
//
@@ -62,8 +63,8 @@ public class DateTimeView extends TextView {
int mLastDisplay = -1;
DateFormat mLastFormat;
private boolean mAttachedToWindow;
private long mUpdateTimeMillis;
private static final ThreadLocal<ReceiverInfo> sReceiverInfo = new ThreadLocal<ReceiverInfo>();
public DateTimeView(Context context) {
super(context);
@@ -76,15 +77,21 @@ public class DateTimeView extends TextView {
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
registerReceivers();
mAttachedToWindow = true;
ReceiverInfo ri = sReceiverInfo.get();
if (ri == null) {
ri = new ReceiverInfo();
sReceiverInfo.set(ri);
}
ri.addView(this);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
unregisterReceivers();
mAttachedToWindow = false;
final ReceiverInfo ri = sReceiverInfo.get();
if (ri != null) {
ri.removeView(this);
}
}
@android.view.RemotableViewMethod
@@ -204,49 +211,86 @@ public class DateTimeView extends TextView {
}
}
private void registerReceivers() {
Context context = getContext();
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);
void clearFormatAndUpdate() {
mLastFormat = null;
update();
}
private void unregisterReceivers() {
Context context = getContext();
context.unregisterReceiver(mBroadcastReceiver);
context.getContentResolver().unregisterContentObserver(mContentObserver);
}
private static class ReceiverInfo {
private final ArrayList<DateTimeView> mAttachedViews = new ArrayList<DateTimeView>();
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (Intent.ACTION_TIME_TICK.equals(action)) {
if (System.currentTimeMillis() < getSoonestUpdateTime()) {
// 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
// every minute.
return;
}
}
// ACTION_TIME_CHANGED can also signal a change of 12/24 hr. format.
updateAll();
}
};
private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (Intent.ACTION_TIME_TICK.equals(action)) {
if (System.currentTimeMillis() < mUpdateTimeMillis) {
// 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
// every minute.
return;
private final ContentObserver mObserver = new ContentObserver(new Handler()) {
@Override
public void onChange(boolean selfChange) {
updateAll();
}
};
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;
}
}
// ACTION_TIME_CHANGED can also signal a change of 12/24 hr. format.
mLastFormat = null;
update();
return result;
}
};
private ContentObserver mContentObserver = new ContentObserver(new Handler()) {
@Override
public void onChange(boolean selfChange) {
mLastFormat = null;
update();
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);
}
}
}