aboutsummaryrefslogtreecommitdiffstats
path: root/main/src/cgeo
diff options
context:
space:
mode:
Diffstat (limited to 'main/src/cgeo')
-rw-r--r--main/src/cgeo/geocaching/activity/Progress.java8
-rw-r--r--main/src/cgeo/geocaching/cgBase.java53
-rw-r--r--main/src/cgeo/geocaching/cgeodetail.java51
-rw-r--r--main/src/cgeo/geocaching/cgeopopup.java11
-rw-r--r--main/src/cgeo/geocaching/connector/AbstractConnector.java5
-rw-r--r--main/src/cgeo/geocaching/connector/GCConnector.java4
-rw-r--r--main/src/cgeo/geocaching/connector/IConnector.java5
-rw-r--r--main/src/cgeo/geocaching/connector/opencaching/ApiOpenCachingConnector.java5
-rw-r--r--main/src/cgeo/geocaching/maps/CGeoMap.java42
-rw-r--r--main/src/cgeo/geocaching/utils/CancellableHandler.java112
10 files changed, 238 insertions, 58 deletions
diff --git a/main/src/cgeo/geocaching/activity/Progress.java b/main/src/cgeo/geocaching/activity/Progress.java
index ddb98b2..6edf23e 100644
--- a/main/src/cgeo/geocaching/activity/Progress.java
+++ b/main/src/cgeo/geocaching/activity/Progress.java
@@ -2,6 +2,7 @@ package cgeo.geocaching.activity;
import android.app.ProgressDialog;
import android.content.Context;
+import android.os.Message;
/**
* progress dialog wrapper for easier management of resources
@@ -17,9 +18,12 @@ public class Progress {
dialog = null;
}
- public synchronized void show(Context context, String title, String message, boolean indeterminate, boolean cancelable) {
+ public synchronized void show(final Context context, final String title, final String message, final boolean indeterminate, final Message cancelMessage) {
if (dialog == null) {
- dialog = ProgressDialog.show(context, title, message, indeterminate, cancelable);
+ dialog = ProgressDialog.show(context, title, message, indeterminate, cancelMessage != null);
+ if (cancelMessage != null) {
+ dialog.setCancelMessage(cancelMessage);
+ }
}
}
diff --git a/main/src/cgeo/geocaching/cgBase.java b/main/src/cgeo/geocaching/cgBase.java
index 66a5891..4f2553a 100644
--- a/main/src/cgeo/geocaching/cgBase.java
+++ b/main/src/cgeo/geocaching/cgBase.java
@@ -12,6 +12,7 @@ import cgeo.geocaching.files.LocParser;
import cgeo.geocaching.geopoint.DistanceParser;
import cgeo.geocaching.geopoint.Geopoint;
import cgeo.geocaching.utils.BaseUtils;
+import cgeo.geocaching.utils.CancellableHandler;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
@@ -995,19 +996,22 @@ public class cgBase {
return caches;
}
- public static cgCacheWrap parseCache(final String page, final int reason, final Handler handler) {
+ public static cgCacheWrap parseCache(final String page, final int reason, final CancellableHandler handler) {
final cgCacheWrap caches = parseCacheFromText(page, reason, handler);
- if (!caches.cacheList.isEmpty()) {
+ if (caches != null && !caches.cacheList.isEmpty()) {
final cgCache cache = caches.cacheList.get(0);
getExtraOnlineInfo(cache, page, handler);
cache.updated = System.currentTimeMillis();
cache.detailedUpdate = cache.updated;
cache.detailed = true;
}
+ if (CancellableHandler.isCancelled(handler)) {
+ return null;
+ }
return caches;
}
- static cgCacheWrap parseCacheFromText(final String page, final int reason, final Handler handler) {
+ static cgCacheWrap parseCacheFromText(final String page, final int reason, final CancellableHandler handler) {
sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_details);
if (StringUtils.isBlank(page)) {
@@ -1203,6 +1207,9 @@ public class cgBase {
try {
final String spoilers = BaseUtils.getMatch(page, GCConstants.PATTERN_SPOILERS, false, null);
if (null != spoilers) {
+ if (CancellableHandler.isCancelled(handler)) {
+ return null;
+ }
sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_spoilers);
final Matcher matcherSpoilersInside = GCConstants.PATTERN_SPOILERSINSIDE.matcher(spoilers);
@@ -1294,6 +1301,9 @@ public class cgBase {
wpBegin = page.indexOf("<table class=\"Table\" id=\"ctl00_ContentBody_Waypoints\">");
if (wpBegin != -1) { // parse waypoints
+ if (CancellableHandler.isCancelled(handler)) {
+ return null;
+ }
sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_waypoints);
final Pattern patternWpType = Pattern.compile("\\/wpttypes\\/sm\\/(.+)\\.jpg", Pattern.CASE_INSENSITIVE);
@@ -1422,15 +1432,24 @@ public class cgBase {
return caches;
}
- private static void getExtraOnlineInfo(final cgCache cache, final String page, final Handler handler) {
+ private static void getExtraOnlineInfo(final cgCache cache, final String page, final CancellableHandler handler) {
+ if (CancellableHandler.isCancelled(handler)) {
+ return;
+ }
sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_logs);
loadLogsFromDetails(page, cache);
+ if (CancellableHandler.isCancelled(handler)) {
+ return;
+ }
sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_elevation);
if (cache.coords != null) {
cache.elevation = getElevation(cache.coords);
}
+ if (CancellableHandler.isCancelled(handler)) {
+ return;
+ }
sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_gcvote);
final cgRating rating = GCVote.getRating(cache.guid, cache.geocode);
if (rating != null) {
@@ -2065,7 +2084,7 @@ public class cgBase {
return search;
}
- public cgSearch searchByGeocode(final String geocode, final String guid, final int reason, final boolean forceReload, final Handler handler) {
+ public cgSearch searchByGeocode(final String geocode, final String guid, final int reason, final boolean forceReload, final CancellableHandler handler) {
final cgSearch search = new cgSearch();
if (StringUtils.isBlank(geocode) && StringUtils.isBlank(guid)) {
@@ -2953,7 +2972,7 @@ public class cgBase {
return path.delete();
}
- public void storeCache(cgeoapplication app, Activity activity, cgCache cache, String geocode, int listId, Handler handler) {
+ public void storeCache(cgeoapplication app, Activity activity, cgCache cache, String geocode, int listId, CancellableHandler handler) {
try {
// get cache details, they may not yet be complete
if (cache != null) {
@@ -2975,6 +2994,10 @@ public class cgBase {
return;
}
+ if (CancellableHandler.isCancelled(handler)) {
+ return;
+ }
+
final cgHtmlImg imgGetter = new cgHtmlImg(activity, cache.geocode, false, listId, true);
// store images from description
@@ -2982,6 +3005,10 @@ public class cgBase {
Html.fromHtml(cache.getDescription(), imgGetter, null);
}
+ if (CancellableHandler.isCancelled(handler)) {
+ return;
+ }
+
// store spoilers
if (CollectionUtils.isNotEmpty(cache.spoilers)) {
for (cgImage oneSpoiler : cache.spoilers) {
@@ -2989,6 +3016,10 @@ public class cgBase {
}
}
+ if (CancellableHandler.isCancelled(handler)) {
+ return;
+ }
+
// store images from logs
if (Settings.isStoreLogImages() && cache.logs != null) {
for (cgLog log : cache.logs) {
@@ -3000,9 +3031,17 @@ public class cgBase {
}
}
+ if (CancellableHandler.isCancelled(handler)) {
+ return;
+ }
+
// store map previews
StaticMapsProvider.downloadMaps(cache, activity);
+ if (CancellableHandler.isCancelled(handler)) {
+ return;
+ }
+
app.markStored(cache.geocode, listId);
app.removeCacheFromCache(cache.geocode);
@@ -3010,7 +3049,7 @@ public class cgBase {
handler.sendMessage(new Message());
}
} catch (Exception e) {
- Log.e(Settings.tag, "cgBase.storeCache: " + e.toString());
+ Log.e(Settings.tag, "cgBase.storeCache");
}
}
diff --git a/main/src/cgeo/geocaching/cgeodetail.java b/main/src/cgeo/geocaching/cgeodetail.java
index 3ba3537..0be24ef 100644
--- a/main/src/cgeo/geocaching/cgeodetail.java
+++ b/main/src/cgeo/geocaching/cgeodetail.java
@@ -8,6 +8,7 @@ import cgeo.geocaching.compatibility.Compatibility;
import cgeo.geocaching.connector.ConnectorFactory;
import cgeo.geocaching.connector.IConnector;
import cgeo.geocaching.enumerations.CacheType;
+import cgeo.geocaching.utils.CancellableHandler;
import cgeo.geocaching.utils.CryptUtils;
import org.apache.commons.collections.CollectionUtils;
@@ -120,9 +121,9 @@ public class cgeodetail extends AbstractActivity {
private Progress progress = new Progress();
- private Handler storeCacheHandler = new Handler() {
+ private class StoreCacheHandler extends CancellableHandler {
@Override
- public void handleMessage(Message msg) {
+ public void handleRegularMessage(Message msg) {
storeThread = null;
try {
@@ -137,9 +138,9 @@ public class cgeodetail extends AbstractActivity {
}
};
- private Handler refreshCacheHandler = new Handler() {
+ private class RefreshCacheHandler extends CancellableHandler {
@Override
- public void handleMessage(Message msg) {
+ public void handleRegularMessage(Message msg) {
refreshThread = null;
try {
@@ -169,9 +170,9 @@ public class cgeodetail extends AbstractActivity {
}
};
- private Handler loadCacheHandler = new Handler() {
+ private class LoadCacheHandler extends CancellableHandler {
@Override
- public void handleMessage(Message msg) {
+ public void handleRegularMessage(final Message msg) {
if (cgBase.UPDATE_LOAD_PROGRESS_DETAIL == msg.what && msg.obj instanceof String) {
updateStatusMsg((String) msg.obj);
} else {
@@ -398,6 +399,8 @@ public class cgeodetail extends AbstractActivity {
app.setAction(geocode);
+ final LoadCacheHandler loadCacheHandler = new LoadCacheHandler();
+
try {
String title = res.getString(R.string.cache);
if (StringUtils.isNotBlank(name)) {
@@ -405,7 +408,7 @@ public class cgeodetail extends AbstractActivity {
} else if (StringUtils.isNotBlank(geocode)) {
title = geocode.toUpperCase();
}
- progress.show(this, title, res.getString(R.string.cache_dialog_loading_details), true, true);
+ progress.show(this, title, res.getString(R.string.cache_dialog_loading_details), true, loadCacheHandler.cancelMessage());
} catch (Exception e) {
// nothing, we lost the window
}
@@ -1361,9 +1364,9 @@ public class cgeodetail extends AbstractActivity {
private class loadCache extends Thread {
- private Handler handler = null;
+ private CancellableHandler handler = null;
- public loadCache(Handler handlerIn) {
+ public loadCache(CancellableHandler handlerIn) {
handler = handlerIn;
if (geocode == null && guid == null) {
@@ -1420,7 +1423,7 @@ public class cgeodetail extends AbstractActivity {
}
public void loadLongDesc() {
- progress.show(this, null, res.getString(R.string.cache_dialog_loading_description), true, true);
+ progress.show(this, null, res.getString(R.string.cache_dialog_loading_description), true, null);
threadLongDesc = new loadLongDesc(loadDescriptionHandler);
threadLongDesc.start();
@@ -1718,7 +1721,9 @@ public class cgeodetail extends AbstractActivity {
return;
}
- progress.show(cgeodetail.this, res.getString(R.string.cache_dialog_offline_save_title), res.getString(R.string.cache_dialog_offline_save_message), true, true);
+ final StoreCacheHandler storeCacheHandler = new StoreCacheHandler();
+
+ progress.show(cgeodetail.this, res.getString(R.string.cache_dialog_offline_save_title), res.getString(R.string.cache_dialog_offline_save_message), true, storeCacheHandler.cancelMessage());
if (storeThread != null) {
storeThread.interrupt();
@@ -1736,7 +1741,9 @@ public class cgeodetail extends AbstractActivity {
return;
}
- progress.show(cgeodetail.this, res.getString(R.string.cache_dialog_refresh_title), res.getString(R.string.cache_dialog_refresh_message), true, true);
+ final RefreshCacheHandler refreshCacheHandler = new RefreshCacheHandler();
+
+ progress.show(cgeodetail.this, res.getString(R.string.cache_dialog_refresh_title), res.getString(R.string.cache_dialog_refresh_message), true, refreshCacheHandler.cancelMessage());
if (refreshThread != null) {
refreshThread.interrupt();
@@ -1748,30 +1755,30 @@ public class cgeodetail extends AbstractActivity {
}
private class storeCacheThread extends Thread {
- private Handler handler = null;
+ final private CancellableHandler handler;
- public storeCacheThread(Handler handlerIn) {
- handler = handlerIn;
+ public storeCacheThread(final CancellableHandler handler) {
+ this.handler = handler;
}
@Override
public void run() {
- int reason = (cache.reason > 1) ? cache.reason : 1;
+ int reason = cache.reason > 1 ? cache.reason : 1;
base.storeCache(app, cgeodetail.this, cache, null, reason, handler);
}
}
private class refreshCacheThread extends Thread {
- private Handler handler = null;
+ final private CancellableHandler handler;
- public refreshCacheThread(Handler handlerIn) {
- handler = handlerIn;
+ public refreshCacheThread(final CancellableHandler handler) {
+ this.handler = handler;
}
@Override
public void run() {
app.removeCacheFromCache(geocode);
- search = base.searchByGeocode(cache.geocode, null, 0, true, null);
+ search = base.searchByGeocode(cache.geocode, null, 0, true, handler);
handler.sendEmptyMessage(0);
}
@@ -1784,7 +1791,7 @@ public class cgeodetail extends AbstractActivity {
return;
}
- progress.show(cgeodetail.this, res.getString(R.string.cache_dialog_offline_drop_title), res.getString(R.string.cache_dialog_offline_drop_message), true, false);
+ progress.show(cgeodetail.this, res.getString(R.string.cache_dialog_offline_drop_title), res.getString(R.string.cache_dialog_offline_drop_message), true, null);
Thread thread = new dropCacheThread(dropCacheHandler);
thread.start();
}
@@ -1813,7 +1820,7 @@ public class cgeodetail extends AbstractActivity {
showToast(res.getString(R.string.err_watchlist_still_managing));
return;
}
- progress.show(cgeodetail.this, res.getString(titleId), res.getString(messageId), true, true);
+ progress.show(cgeodetail.this, res.getString(titleId), res.getString(messageId), true, null);
if (watchlistThread != null) {
watchlistThread.interrupt();
diff --git a/main/src/cgeo/geocaching/cgeopopup.java b/main/src/cgeo/geocaching/cgeopopup.java
index 9f22164..ec9d9f7 100644
--- a/main/src/cgeo/geocaching/cgeopopup.java
+++ b/main/src/cgeo/geocaching/cgeopopup.java
@@ -3,6 +3,7 @@ package cgeo.geocaching;
import cgeo.geocaching.activity.AbstractActivity;
import cgeo.geocaching.apps.cache.navi.NavigationAppFactory;
import cgeo.geocaching.enumerations.CacheType;
+import cgeo.geocaching.utils.CancellableHandler;
import org.apache.commons.lang3.StringUtils;
@@ -53,10 +54,10 @@ public class cgeopopup extends AbstractActivity {
}
}
};
- private Handler storeCacheHandler = new Handler() {
+ private CancellableHandler storeCacheHandler = new CancellableHandler() {
@Override
- public void handleMessage(Message msg) {
+ public void handleRegularMessage(Message msg) {
try {
if (storeDialog != null) {
storeDialog.dismiss();
@@ -566,10 +567,10 @@ public class cgeopopup extends AbstractActivity {
private class storeCacheThread extends Thread {
- private Handler handler = null;
+ final private CancellableHandler handler;
- public storeCacheThread(Handler handlerIn) {
- handler = handlerIn;
+ public storeCacheThread(final CancellableHandler handler) {
+ this.handler = handler;
}
@Override
diff --git a/main/src/cgeo/geocaching/connector/AbstractConnector.java b/main/src/cgeo/geocaching/connector/AbstractConnector.java
index 4153c76..a0ed628 100644
--- a/main/src/cgeo/geocaching/connector/AbstractConnector.java
+++ b/main/src/cgeo/geocaching/connector/AbstractConnector.java
@@ -4,8 +4,7 @@ import cgeo.geocaching.cgBase;
import cgeo.geocaching.cgCache;
import cgeo.geocaching.cgSearch;
import cgeo.geocaching.cgeoapplication;
-
-import android.os.Handler;
+import cgeo.geocaching.utils.CancellableHandler;
public abstract class AbstractConnector implements IConnector {
@@ -45,7 +44,7 @@ public abstract class AbstractConnector implements IConnector {
}
@Override
- public cgSearch searchByGeocode(cgBase base, String geocode, String guid, cgeoapplication app, cgSearch search, int reason, Handler handler) {
+ public cgSearch searchByGeocode(cgBase base, String geocode, String guid, cgeoapplication app, cgSearch search, int reason, CancellableHandler handler) {
return null;
}
diff --git a/main/src/cgeo/geocaching/connector/GCConnector.java b/main/src/cgeo/geocaching/connector/GCConnector.java
index 51dca6d..3c2709f 100644
--- a/main/src/cgeo/geocaching/connector/GCConnector.java
+++ b/main/src/cgeo/geocaching/connector/GCConnector.java
@@ -8,11 +8,11 @@ import cgeo.geocaching.cgCache;
import cgeo.geocaching.cgCacheWrap;
import cgeo.geocaching.cgSearch;
import cgeo.geocaching.cgeoapplication;
+import cgeo.geocaching.utils.CancellableHandler;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
-import android.os.Handler;
import android.util.Log;
import java.util.ArrayList;
@@ -67,7 +67,7 @@ public class GCConnector extends AbstractConnector implements IConnector {
}
@Override
- public cgSearch searchByGeocode(final cgBase base, String geocode, final String guid, final cgeoapplication app, final cgSearch search, final int reason, final Handler handler) {
+ public cgSearch searchByGeocode(final cgBase base, String geocode, final String guid, final cgeoapplication app, final cgSearch search, final int reason, final CancellableHandler handler) {
final Parameters params = new Parameters("decrypt", "y");
if (StringUtils.isNotBlank(geocode)) {
params.put("wp", geocode);
diff --git a/main/src/cgeo/geocaching/connector/IConnector.java b/main/src/cgeo/geocaching/connector/IConnector.java
index 54962bb..89a94a1 100644
--- a/main/src/cgeo/geocaching/connector/IConnector.java
+++ b/main/src/cgeo/geocaching/connector/IConnector.java
@@ -4,8 +4,7 @@ import cgeo.geocaching.cgBase;
import cgeo.geocaching.cgCache;
import cgeo.geocaching.cgSearch;
import cgeo.geocaching.cgeoapplication;
-
-import android.os.Handler;
+import cgeo.geocaching.utils.CancellableHandler;
public interface IConnector {
/**
@@ -76,5 +75,5 @@ public interface IConnector {
*/
public boolean supportsCachesAround();
- public cgSearch searchByGeocode(final cgBase base, final String geocode, final String guid, final cgeoapplication app, final cgSearch search, final int reason, final Handler handler);
+ public cgSearch searchByGeocode(final cgBase base, final String geocode, final String guid, final cgeoapplication app, final cgSearch search, final int reason, final CancellableHandler handler);
}
diff --git a/main/src/cgeo/geocaching/connector/opencaching/ApiOpenCachingConnector.java b/main/src/cgeo/geocaching/connector/opencaching/ApiOpenCachingConnector.java
index 3c193d9..8660d2a 100644
--- a/main/src/cgeo/geocaching/connector/opencaching/ApiOpenCachingConnector.java
+++ b/main/src/cgeo/geocaching/connector/opencaching/ApiOpenCachingConnector.java
@@ -7,10 +7,9 @@ import cgeo.geocaching.cgCacheWrap;
import cgeo.geocaching.cgSearch;
import cgeo.geocaching.cgeoapplication;
import cgeo.geocaching.connector.IConnector;
+import cgeo.geocaching.utils.CancellableHandler;
import cgeo.geocaching.utils.CryptUtils;
-import android.os.Handler;
-
import java.util.List;
public class ApiOpenCachingConnector extends OpenCachingConnector implements IConnector {
@@ -38,7 +37,7 @@ public class ApiOpenCachingConnector extends OpenCachingConnector implements ICo
}
@Override
- public cgSearch searchByGeocode(final cgBase base, final String geocode, final String guid, final cgeoapplication app, final cgSearch search, final int reason, final Handler handler) {
+ public cgSearch searchByGeocode(final cgBase base, final String geocode, final String guid, final cgeoapplication app, final cgSearch search, final int reason, final CancellableHandler handler) {
final cgCache cache = OkapiClient.getCache(geocode);
if (cache == null) {
return null;
diff --git a/main/src/cgeo/geocaching/maps/CGeoMap.java b/main/src/cgeo/geocaching/maps/CGeoMap.java
index 4c693a6..3d227b1 100644
--- a/main/src/cgeo/geocaching/maps/CGeoMap.java
+++ b/main/src/cgeo/geocaching/maps/CGeoMap.java
@@ -27,6 +27,7 @@ import cgeo.geocaching.maps.interfaces.MapFactory;
import cgeo.geocaching.maps.interfaces.MapViewImpl;
import cgeo.geocaching.maps.interfaces.OnDragListener;
import cgeo.geocaching.maps.interfaces.OtherCachersOverlayItemImpl;
+import cgeo.geocaching.utils.CancellableHandler;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
@@ -206,10 +207,11 @@ public class CGeoMap extends AbstractMap implements OnDragListener, ViewFactory
}
}
};
- final private Handler loadDetailsHandler = new Handler() {
+
+ final private class LoadDetailsHandler extends CancellableHandler {
@Override
- public void handleMessage(Message msg) {
+ public void handleRegularMessage(Message msg) {
if (msg.what == 0) {
if (waitDialog != null) {
int secondsElapsed = (int) ((System.currentTimeMillis() - detailProgressTime) / 1000);
@@ -243,6 +245,21 @@ public class CGeoMap extends AbstractMap implements OnDragListener, ViewFactory
}
}
}
+
+ @Override
+ public void handleCancel(final Object extra) {
+ if (loadDetailsThread != null) {
+ loadDetailsThread.stopIt();
+ }
+
+ if (geo == null) {
+ geo = app.startGeo(activity, geoUpdate, base, 0, 0);
+ }
+ if (Settings.isUseCompass() && dir == null) {
+ dir = app.startDir(activity, dirUpdate);
+ }
+ }
+
};
final private Handler noMapTokenHandler = new Handler() {
@@ -617,9 +634,12 @@ public class CGeoMap extends AbstractMap implements OnDragListener, ViewFactory
return true;
}
+ final LoadDetailsHandler loadDetailsHandler = new LoadDetailsHandler();
+
waitDialog = new ProgressDialog(activity);
waitDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
waitDialog.setCancelable(true);
+ waitDialog.setCancelMessage(loadDetailsHandler.cancelMessage());
waitDialog.setMax(detailTotal);
waitDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
@@ -1636,18 +1656,17 @@ public class CGeoMap extends AbstractMap implements OnDragListener, ViewFactory
private class LoadDetails extends Thread {
- private Handler handler = null;
- private List<String> geocodes = null;
- private volatile boolean stop = false;
+ final private CancellableHandler handler;
+ final private List<String> geocodes;
private long last = 0L;
- public LoadDetails(Handler handlerIn, List<String> geocodesIn) {
- handler = handlerIn;
- geocodes = geocodesIn;
+ public LoadDetails(final CancellableHandler handler, final List<String> geocodes) {
+ this.handler = handler;
+ this.geocodes = geocodes;
}
public void stopIt() {
- stop = true;
+ handler.cancel();
}
@Override
@@ -1665,7 +1684,7 @@ public class CGeoMap extends AbstractMap implements OnDragListener, ViewFactory
for (String geocode : geocodes) {
try {
- if (stop) {
+ if (handler.isCancelled()) {
break;
}
@@ -1683,7 +1702,7 @@ public class CGeoMap extends AbstractMap implements OnDragListener, ViewFactory
}
}
- if (stop) {
+ if (handler.isCancelled()) {
Log.i(Settings.tag, "Stopped storing process.");
break;
@@ -1699,6 +1718,7 @@ public class CGeoMap extends AbstractMap implements OnDragListener, ViewFactory
handler.sendEmptyMessage(0);
}
+ // FIXME: what does this yield() do here?
yield();
last = System.currentTimeMillis();
diff --git a/main/src/cgeo/geocaching/utils/CancellableHandler.java b/main/src/cgeo/geocaching/utils/CancellableHandler.java
new file mode 100644
index 0000000..0b490d8
--- /dev/null
+++ b/main/src/cgeo/geocaching/utils/CancellableHandler.java
@@ -0,0 +1,112 @@
+package cgeo.geocaching.utils;
+
+import android.os.Handler;
+import android.os.Message;
+
+/**
+ * Handler with a cancel policy. Once cancelled, the handler will not handle
+ * any more cancel or regular message.
+ */
+public abstract class CancellableHandler extends Handler {
+
+ private boolean cancelled = false;
+
+ private static class CancelHolder {
+ final Object payload;
+
+ CancelHolder(final Object payload) {
+ this.payload = payload;
+ }
+ }
+
+ @Override
+ final public void handleMessage(final Message message) {
+ if (cancelled) {
+ return;
+ }
+
+ if (message.obj instanceof CancelHolder) {
+ cancelled = true;
+ handleCancel(((CancelHolder) message.obj).payload);
+ } else {
+ handleRegularMessage(message);
+ }
+ }
+
+ /**
+ * Handle a non-cancel message.<br>
+ * Subclasses must implement this to handle messages.
+ *
+ * @param message
+ * the message to handle
+ */
+ abstract protected void handleRegularMessage(final Message message);
+
+ /**
+ * Handle a cancel message.
+ *
+ * @param extra
+ * the additional payload given by the canceller
+ */
+ protected void handleCancel(final Object extra) {
+ }
+
+ /**
+ * Get a cancel message that can later be sent to this handler to cancel it.
+ *
+ * @return a cancel message
+ */
+ public Message cancelMessage() {
+ return cancelMessage(null);
+ }
+
+ /**
+ * Get a cancel message with an additional parameter that can later be sent to
+ * this handler to cancel it.
+ *
+ * @param extra
+ * the extra parameter to give to the cancel handler
+ * @return a cancel message
+ */
+ public Message cancelMessage(final Object extra) {
+ return this.obtainMessage(0, new CancelHolder(extra));
+ }
+
+ /**
+ * Cancel the current handler. This can be called from any thread.
+ */
+ public void cancel() {
+ cancel(null);
+ }
+
+ /**
+ * Cancel the current handler. This can be called from any thread.
+ *
+ * @param extra
+ * the extra parameter to give to the cancel handler
+ */
+ public void cancel(final Object extra) {
+ cancelMessage(extra).sendToTarget();
+ }
+
+ /**
+ * Check if the current handler has been cancelled.
+ *
+ * @return true if the handler has been cancelled
+ */
+ public boolean isCancelled() {
+ return cancelled;
+ }
+
+ /**
+ * Check if a handler has been cancelled.
+ *
+ * @param handler
+ * a handler, or null
+ * @return true if the handler is not null and has been cancelled
+ */
+ public static boolean isCancelled(final CancellableHandler handler) {
+ return handler != null && handler.isCancelled();
+ }
+
+}