Merge "Fix 3106227: use WeakReferences for receivers in DigitalClock class" into gingerbread

This commit is contained in:
Jim Miller
2011-01-16 16:14:52 -08:00
committed by Android (Google) Code Review
6 changed files with 87 additions and 53 deletions

View File

@@ -22,7 +22,6 @@ import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.content.res.Resources;
import android.database.ContentObserver; import android.database.ContentObserver;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.os.Handler; import android.os.Handler;
@@ -33,6 +32,7 @@ import android.view.View;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import java.lang.ref.WeakReference;
import java.text.DateFormatSymbols; import java.text.DateFormatSymbols;
import java.util.Calendar; import java.util.Calendar;
@@ -49,26 +49,41 @@ public class DigitalClock extends LinearLayout {
private TextView mTimeDisplay; private TextView mTimeDisplay;
private AmPm mAmPm; private AmPm mAmPm;
private ContentObserver mFormatChangeObserver; private ContentObserver mFormatChangeObserver;
private boolean mLive = true; private int mAttached = 0; // for debugging - tells us whether attach/detach is unbalanced
private boolean mAttached;
/* called by system on minute ticks */ /* called by system on minute ticks */
private final Handler mHandler = new Handler(); private final Handler mHandler = new Handler();
private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { private BroadcastReceiver mIntentReceiver;
@Override
public void onReceive(Context context, Intent intent) { private static class TimeChangedReceiver extends BroadcastReceiver {
if (mLive && intent.getAction().equals( private WeakReference<DigitalClock> mClock;
Intent.ACTION_TIMEZONE_CHANGED)) { private Context mContext;
mCalendar = Calendar.getInstance();
} public TimeChangedReceiver(DigitalClock clock) {
// Post a runnable to avoid blocking the broadcast. mClock = new WeakReference<DigitalClock>(clock);
mHandler.post(new Runnable() { mContext = clock.getContext();
public void run() { }
updateTime();
@Override
public void onReceive(Context context, Intent intent) {
// Post a runnable to avoid blocking the broadcast.
final boolean timezoneChanged =
intent.getAction().equals(Intent.ACTION_TIMEZONE_CHANGED);
final DigitalClock clock = mClock.get();
if (clock != null) {
clock.mHandler.post(new Runnable() {
public void run() {
if (timezoneChanged) {
clock.mCalendar = Calendar.getInstance();
} }
clock.updateTime();
}
}); });
} else {
mContext.unregisterReceiver(this);
} }
}; }
};
static class AmPm { static class AmPm {
private TextView mAmPm; private TextView mAmPm;
@@ -94,14 +109,23 @@ public class DigitalClock extends LinearLayout {
} }
} }
private class FormatChangeObserver extends ContentObserver { private static class FormatChangeObserver extends ContentObserver {
public FormatChangeObserver() { private WeakReference<DigitalClock> mClock;
private Context mContext;
public FormatChangeObserver(DigitalClock clock) {
super(new Handler()); super(new Handler());
mClock = new WeakReference<DigitalClock>(clock);
mContext = clock.getContext();
} }
@Override @Override
public void onChange(boolean selfChange) { public void onChange(boolean selfChange) {
setDateFormat(); DigitalClock digitalClock = mClock.get();
updateTime(); if (digitalClock != null) {
digitalClock.setDateFormat();
digitalClock.updateTime();
} else {
mContext.getContentResolver().unregisterContentObserver(this);
}
} }
} }
@@ -129,11 +153,11 @@ public class DigitalClock extends LinearLayout {
protected void onAttachedToWindow() { protected void onAttachedToWindow() {
super.onAttachedToWindow(); super.onAttachedToWindow();
if (mAttached) return; mAttached++;
mAttached = true;
if (mLive) { /* monitor time ticks, time changed, timezone */
/* monitor time ticks, time changed, timezone */ if (mIntentReceiver == null) {
mIntentReceiver = new TimeChangedReceiver(this);
IntentFilter filter = new IntentFilter(); IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_TIME_TICK); filter.addAction(Intent.ACTION_TIME_TICK);
filter.addAction(Intent.ACTION_TIME_CHANGED); filter.addAction(Intent.ACTION_TIME_CHANGED);
@@ -142,9 +166,11 @@ public class DigitalClock extends LinearLayout {
} }
/* monitor 12/24-hour display preference */ /* monitor 12/24-hour display preference */
mFormatChangeObserver = new FormatChangeObserver(); if (mFormatChangeObserver == null) {
mContext.getContentResolver().registerContentObserver( mFormatChangeObserver = new FormatChangeObserver(this);
Settings.System.CONTENT_URI, true, mFormatChangeObserver); mContext.getContentResolver().registerContentObserver(
Settings.System.CONTENT_URI, true, mFormatChangeObserver);
}
updateTime(); updateTime();
} }
@@ -153,16 +179,19 @@ public class DigitalClock extends LinearLayout {
protected void onDetachedFromWindow() { protected void onDetachedFromWindow() {
super.onDetachedFromWindow(); super.onDetachedFromWindow();
if (!mAttached) return; mAttached--;
mAttached = false;
if (mLive) { if (mIntentReceiver != null) {
mContext.unregisterReceiver(mIntentReceiver); mContext.unregisterReceiver(mIntentReceiver);
} }
mContext.getContentResolver().unregisterContentObserver( if (mFormatChangeObserver != null) {
mFormatChangeObserver); mContext.getContentResolver().unregisterContentObserver(
} mFormatChangeObserver);
}
mFormatChangeObserver = null;
mIntentReceiver = null;
}
void updateTime(Calendar c) { void updateTime(Calendar c) {
mCalendar = c; mCalendar = c;
@@ -170,9 +199,7 @@ public class DigitalClock extends LinearLayout {
} }
private void updateTime() { private void updateTime() {
if (mLive) { mCalendar.setTimeInMillis(System.currentTimeMillis());
mCalendar.setTimeInMillis(System.currentTimeMillis());
}
CharSequence newTime = DateFormat.format(mFormat, mCalendar); CharSequence newTime = DateFormat.format(mFormat, mCalendar);
mTimeDisplay.setText(newTime); mTimeDisplay.setText(newTime);
@@ -184,8 +211,4 @@ public class DigitalClock extends LinearLayout {
? M24 : M12; ? M24 : M12;
mAmPm.setShowAmPm(mFormat.equals(M12)); mAmPm.setShowAmPm(mFormat.equals(M12));
} }
void setLive(boolean live) {
mLive = live;
}
} }

View File

@@ -62,8 +62,8 @@ public class AccountUnlockScreen extends RelativeLayout implements KeyguardScree
*/ */
private static final int AWAKE_POKE_MILLIS = 30000; private static final int AWAKE_POKE_MILLIS = 30000;
private final KeyguardScreenCallback mCallback; private KeyguardScreenCallback mCallback;
private final LockPatternUtils mLockPatternUtils; private LockPatternUtils mLockPatternUtils;
private KeyguardUpdateMonitor mUpdateMonitor; private KeyguardUpdateMonitor mUpdateMonitor;
private TextView mTopHeader; private TextView mTopHeader;
@@ -159,7 +159,10 @@ public class AccountUnlockScreen extends RelativeLayout implements KeyguardScree
if (mCheckingDialog != null) { if (mCheckingDialog != null) {
mCheckingDialog.hide(); mCheckingDialog.hide();
} }
mUpdateMonitor.removeCallback(this); mUpdateMonitor.removeCallback(this); // this must be first
mCallback = null;
mLockPatternUtils = null;
mUpdateMonitor = null;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */

View File

@@ -223,8 +223,8 @@ public class KeyguardViewManager implements KeyguardWindowController {
mKeyguardHost.postDelayed(new Runnable() { mKeyguardHost.postDelayed(new Runnable() {
public void run() { public void run() {
synchronized (KeyguardViewManager.this) { synchronized (KeyguardViewManager.this) {
mKeyguardHost.removeView(lastView);
lastView.cleanUp(); lastView.cleanUp();
mKeyguardHost.removeView(lastView);
} }
} }
}, 500); }, 500);

View File

@@ -495,8 +495,10 @@ public class LockPatternKeyguardView extends KeyguardViewBase {
public void cleanUp() { public void cleanUp() {
((KeyguardScreen) mLockScreen).onPause(); ((KeyguardScreen) mLockScreen).onPause();
((KeyguardScreen) mLockScreen).cleanUp(); ((KeyguardScreen) mLockScreen).cleanUp();
this.removeView(mLockScreen);
((KeyguardScreen) mUnlockScreen).onPause(); ((KeyguardScreen) mUnlockScreen).onPause();
((KeyguardScreen) mUnlockScreen).cleanUp(); ((KeyguardScreen) mUnlockScreen).cleanUp();
this.removeView(mUnlockScreen);
} }
private boolean isSecure() { private boolean isSecure() {

View File

@@ -55,9 +55,9 @@ class LockScreen extends LinearLayout implements KeyguardScreen, KeyguardUpdateM
private Status mStatus = Status.Normal; private Status mStatus = Status.Normal;
private final LockPatternUtils mLockPatternUtils; private LockPatternUtils mLockPatternUtils;
private final KeyguardUpdateMonitor mUpdateMonitor; private KeyguardUpdateMonitor mUpdateMonitor;
private final KeyguardScreenCallback mCallback; private KeyguardScreenCallback mCallback;
private TextView mCarrier; private TextView mCarrier;
private SlidingTab mSelector; private SlidingTab mSelector;
@@ -225,8 +225,8 @@ class LockScreen extends LinearLayout implements KeyguardScreen, KeyguardUpdateM
setFocusableInTouchMode(true); setFocusableInTouchMode(true);
setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS); setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
updateMonitor.registerInfoCallback(this); mUpdateMonitor.registerInfoCallback(this);
updateMonitor.registerSimStateCallback(this); mUpdateMonitor.registerSimStateCallback(this);
mAudioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE); mAudioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
mSilentMode = isSilentMode(); mSilentMode = isSilentMode();
@@ -668,7 +668,10 @@ class LockScreen extends LinearLayout implements KeyguardScreen, KeyguardUpdateM
/** {@inheritDoc} */ /** {@inheritDoc} */
public void cleanUp() { public void cleanUp() {
mUpdateMonitor.removeCallback(this); mUpdateMonitor.removeCallback(this); // this must be first
mLockPatternUtils = null;
mUpdateMonitor = null;
mCallback = null;
} }
/** {@inheritDoc} */ /** {@inheritDoc} */

View File

@@ -66,9 +66,9 @@ class PatternUnlockScreen extends LinearLayoutWithDefaultTouchRecepient
private int mTotalFailedPatternAttempts = 0; private int mTotalFailedPatternAttempts = 0;
private CountDownTimer mCountdownTimer = null; private CountDownTimer mCountdownTimer = null;
private final LockPatternUtils mLockPatternUtils; private LockPatternUtils mLockPatternUtils;
private final KeyguardUpdateMonitor mUpdateMonitor; private KeyguardUpdateMonitor mUpdateMonitor;
private final KeyguardScreenCallback mCallback; private KeyguardScreenCallback mCallback;
/** /**
* whether there is a fallback option available when the pattern is forgotten. * whether there is a fallback option available when the pattern is forgotten.
@@ -478,6 +478,9 @@ class PatternUnlockScreen extends LinearLayoutWithDefaultTouchRecepient
/** {@inheritDoc} */ /** {@inheritDoc} */
public void cleanUp() { public void cleanUp() {
mUpdateMonitor.removeCallback(this); mUpdateMonitor.removeCallback(this);
mLockPatternUtils = null;
mUpdateMonitor = null;
mCallback = null;
} }
@Override @Override