diff options
| author | Samuel Tardieu <sam@rfc1149.net> | 2013-05-25 15:30:11 +0200 |
|---|---|---|
| committer | Samuel Tardieu <sam@rfc1149.net> | 2013-05-25 15:30:11 +0200 |
| commit | 43a0f4dfd94e0b47a60ddddcf58561dccecbac17 (patch) | |
| tree | e63ce522ff4986b2ce00b2579d0c0b73bb1e5c92 | |
| parent | da2451acb8169ae0380341f167f9f45fa1e92f7a (diff) | |
| download | cgeo-43a0f4dfd94e0b47a60ddddcf58561dccecbac17.zip cgeo-43a0f4dfd94e0b47a60ddddcf58561dccecbac17.tar.gz cgeo-43a0f4dfd94e0b47a60ddddcf58561dccecbac17.tar.bz2 | |
refactoring: make periodic handler use weak references
PeriodicHandler now uses weak references to keep a link to the looper
that requested it. This way, it will not prevent the source from being
garbage collected even though a delayed message may be queued in the
handler.
Also, at the next iteration, the periodic handler will notice that its
starter looper has been garbage collected and will stop itself if it has
not been already.
| -rw-r--r-- | main/src/cgeo/geocaching/network/StatusUpdater.java | 13 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/ui/CompassView.java | 33 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/utils/PeriodicHandler.java | 33 |
3 files changed, 40 insertions, 39 deletions
diff --git a/main/src/cgeo/geocaching/network/StatusUpdater.java b/main/src/cgeo/geocaching/network/StatusUpdater.java index 1953e1d..bfc77ba 100644 --- a/main/src/cgeo/geocaching/network/StatusUpdater.java +++ b/main/src/cgeo/geocaching/network/StatusUpdater.java @@ -3,6 +3,7 @@ package cgeo.geocaching.network; import cgeo.geocaching.cgeoapplication; import cgeo.geocaching.utils.MemorySubject; import cgeo.geocaching.utils.PeriodicHandler; +import cgeo.geocaching.utils.PeriodicHandler.PeriodicHandlerListener; import cgeo.geocaching.utils.Version; import org.json.JSONException; @@ -12,7 +13,7 @@ import android.os.Looper; import java.util.Locale; -public class StatusUpdater extends MemorySubject<StatusUpdater.Status> implements Runnable { +public class StatusUpdater extends MemorySubject<StatusUpdater.Status> implements Runnable, PeriodicHandlerListener { static public class Status { final public String message; @@ -28,7 +29,8 @@ public class StatusUpdater extends MemorySubject<StatusUpdater.Status> implement } } - private void requestUpdate() { + @Override + public void onPeriodic() { final JSONObject response = Network.requestJSON("http://status.cgeo.org/api/status.json", new Parameters("version_code", String.valueOf(Version.getVersionCode(cgeoapplication.getInstance())), @@ -50,12 +52,7 @@ public class StatusUpdater extends MemorySubject<StatusUpdater.Status> implement @Override public void run() { Looper.prepare(); - new PeriodicHandler(1800000L) { - @Override - public void act() { - requestUpdate(); - } - }.start(); + new PeriodicHandler(1800000L, this).start(); Looper.loop(); } diff --git a/main/src/cgeo/geocaching/ui/CompassView.java b/main/src/cgeo/geocaching/ui/CompassView.java index 0ef3a43..c926057 100644 --- a/main/src/cgeo/geocaching/ui/CompassView.java +++ b/main/src/cgeo/geocaching/ui/CompassView.java @@ -3,6 +3,7 @@ package cgeo.geocaching.ui; import cgeo.geocaching.R; import cgeo.geocaching.utils.AngleUtils; import cgeo.geocaching.utils.PeriodicHandler; +import cgeo.geocaching.utils.PeriodicHandler.PeriodicHandlerListener; import android.content.Context; import android.graphics.Bitmap; @@ -14,7 +15,7 @@ import android.util.AttributeSet; import android.util.FloatMath; import android.view.View; -public class CompassView extends View { +public class CompassView extends View implements PeriodicHandlerListener { private Context context = null; private Bitmap compassUnderlay = null; @@ -48,7 +49,7 @@ public class CompassView extends View { private int compassOverlayWidth = 0; private int compassOverlayHeight = 0; private boolean initialDisplay; - private final RedrawHandler redrawHandler = new RedrawHandler(); + private final PeriodicHandler redrawHandler = new PeriodicHandler(40, this); public CompassView(Context contextIn) { super(contextIn); @@ -145,26 +146,18 @@ public class CompassView extends View { return AngleUtils.normalize(actual + offset); } - private class RedrawHandler extends PeriodicHandler { - - public RedrawHandler() { - super(40); - } - - @Override - public void act() { - final float newAzimuthShown = smoothUpdate(northMeasured, azimuthShown); - final float newCacheHeadingShown = smoothUpdate(cacheHeadingMeasured, cacheHeadingShown); - if (Math.abs(AngleUtils.difference(azimuthShown, newAzimuthShown)) >= 2 || - Math.abs(AngleUtils.difference(cacheHeadingShown, newCacheHeadingShown)) >= 2) { - synchronized(CompassView.this) { - azimuthShown = newAzimuthShown; - cacheHeadingShown = newCacheHeadingShown; - } - invalidate(); + @Override + public void onPeriodic() { + final float newAzimuthShown = smoothUpdate(northMeasured, azimuthShown); + final float newCacheHeadingShown = smoothUpdate(cacheHeadingMeasured, cacheHeadingShown); + if (Math.abs(AngleUtils.difference(azimuthShown, newAzimuthShown)) >= 2 || + Math.abs(AngleUtils.difference(cacheHeadingShown, newCacheHeadingShown)) >= 2) { + synchronized(this) { + azimuthShown = newAzimuthShown; + cacheHeadingShown = newCacheHeadingShown; } + invalidate(); } - } @Override diff --git a/main/src/cgeo/geocaching/utils/PeriodicHandler.java b/main/src/cgeo/geocaching/utils/PeriodicHandler.java index 2759580..288bbb0 100644 --- a/main/src/cgeo/geocaching/utils/PeriodicHandler.java +++ b/main/src/cgeo/geocaching/utils/PeriodicHandler.java @@ -3,16 +3,26 @@ package cgeo.geocaching.utils; import android.os.Handler; import android.os.Message; +import java.lang.ref.WeakReference; + /** * A PeriodicHandler class helps with the implementation of a periodic * action embedded in a thread with a looper such as the UI thread. - * The act() method will be called periodically. The clock may drift - * as the implementation does not target real-time actions. + * The onPeriodic() method of the listener will be called periodically. + * The clock may drift as the implementation does not target real-time + * actions. * * The handler will be interrupted if the device goes to sleep. * + * The handler only keeps a weak reference to the listener. If the listener + * is garbage-collected without having stopped the timer, the handler will + * stop itself. */ -abstract public class PeriodicHandler extends Handler { +final public class PeriodicHandler extends Handler { + + public static interface PeriodicHandlerListener { + public void onPeriodic(); + } final static private int START = 0; final static private int STOP = 1; @@ -20,21 +30,19 @@ abstract public class PeriodicHandler extends Handler { final private long period; + final private WeakReference<PeriodicHandlerListener> listenerRef; + /** * Create a new PeriodicHandler object. * * @param period * The period in milliseconds. */ - protected PeriodicHandler(final long period) { + public PeriodicHandler(final long period, final PeriodicHandlerListener listener) { this.period = period; + listenerRef = new WeakReference<PeriodicHandlerListener>(listener); } - /** - * Subclasses of PeriodicHandler must implement this method. - */ - abstract public void act(); - @Override public void handleMessage(final Message msg) { switch (msg.what) { @@ -46,8 +54,11 @@ abstract public class PeriodicHandler extends Handler { removeMessages(ACT); break; case ACT: - sendEmptyMessageDelayed(ACT, period); - act(); + final PeriodicHandlerListener listener = listenerRef.get(); + if (listener != null) { + sendEmptyMessageDelayed(ACT, period); + listener.onPeriodic(); + } break; default: throw new UnsupportedOperationException(); |
