diff options
| author | rsudev <rasch@munin-soft.de> | 2011-08-25 23:04:29 +0200 |
|---|---|---|
| committer | rsudev <rasch@munin-soft.de> | 2011-08-25 23:04:29 +0200 |
| commit | 6bdc89b3cbb00dfaaf5716b1cbb76962ddc2ad24 (patch) | |
| tree | 85e341486e79223904c38c9a71a3572143a68635 | |
| parent | 5db059cb2b0b3872490a1eefdac93fad4bb55a18 (diff) | |
| download | cgeo-6bdc89b3cbb00dfaaf5716b1cbb76962ddc2ad24.zip cgeo-6bdc89b3cbb00dfaaf5716b1cbb76962ddc2ad24.tar.gz cgeo-6bdc89b3cbb00dfaaf5716b1cbb76962ddc2ad24.tar.bz2 | |
Fix for #209 (ArrayIndexOutOfBounds in google map
Implemented lock as suggested by BKFC
| -rw-r--r-- | src/cgeo/geocaching/googlemaps/googleCacheOverlay.java | 15 | ||||
| -rw-r--r-- | src/cgeo/geocaching/googlemaps/googleOverlay.java | 14 | ||||
| -rw-r--r-- | src/cgeo/geocaching/googlemaps/googleUsersOverlay.java | 16 | ||||
| -rw-r--r-- | src/cgeo/geocaching/mapcommon/cgMapOverlay.java | 122 | ||||
| -rw-r--r-- | src/cgeo/geocaching/mapinterfaces/OverlayImpl.java | 4 | ||||
| -rw-r--r-- | src/cgeo/geocaching/mapsforge/mfCacheOverlay.java | 14 | ||||
| -rw-r--r-- | src/cgeo/geocaching/mapsforge/mfOverlay.java | 14 | ||||
| -rw-r--r-- | src/cgeo/geocaching/mapsforge/mfUsersOverlay.java | 14 |
8 files changed, 163 insertions, 50 deletions
diff --git a/src/cgeo/geocaching/googlemaps/googleCacheOverlay.java b/src/cgeo/geocaching/googlemaps/googleCacheOverlay.java index 68929cf..02e8c04 100644 --- a/src/cgeo/geocaching/googlemaps/googleCacheOverlay.java +++ b/src/cgeo/geocaching/googlemaps/googleCacheOverlay.java @@ -1,10 +1,12 @@ package cgeo.geocaching.googlemaps; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + import android.content.Context; import android.graphics.Canvas; import android.graphics.Point; import android.graphics.drawable.Drawable; - import cgeo.geocaching.cgSettings; import cgeo.geocaching.mapcommon.cgMapOverlay; import cgeo.geocaching.mapinterfaces.ItemizedOverlayImpl; @@ -22,6 +24,7 @@ import com.google.android.maps.MapView; public class googleCacheOverlay extends ItemizedOverlay<googleCacheOverlayItem> implements ItemizedOverlayImpl { private cgMapOverlay base; + private Lock lock = new ReentrantLock(); public googleCacheOverlay(cgSettings settingsIn, Context contextIn, Drawable markerIn, Boolean fromDetailIn) { super(boundCenterBottom(markerIn)); @@ -98,4 +101,14 @@ public class googleCacheOverlay extends ItemizedOverlay<googleCacheOverlayItem> // Nothing to do here... } + @Override + public void lock() { + lock.lock(); + } + + @Override + public void unlock() { + lock.unlock(); + } + } diff --git a/src/cgeo/geocaching/googlemaps/googleOverlay.java b/src/cgeo/geocaching/googlemaps/googleOverlay.java index 97909be..8473faa 100644 --- a/src/cgeo/geocaching/googlemaps/googleOverlay.java +++ b/src/cgeo/geocaching/googlemaps/googleOverlay.java @@ -1,5 +1,8 @@ package cgeo.geocaching.googlemaps; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + import android.app.Activity; import android.graphics.Canvas; import cgeo.geocaching.cgSettings; @@ -15,6 +18,7 @@ import com.google.android.maps.Overlay; public class googleOverlay extends Overlay implements OverlayImpl { private OverlayBase overlayBase = null; + private Lock lock = new ReentrantLock(); public googleOverlay(Activity activityIn, cgSettings settingsIn, overlayType ovlType) { switch (ovlType) { @@ -38,4 +42,14 @@ public class googleOverlay extends Overlay implements OverlayImpl { public OverlayBase getBase() { return overlayBase; } + + @Override + public void lock() { + lock.lock(); + } + + @Override + public void unlock() { + lock.unlock(); + } } diff --git a/src/cgeo/geocaching/googlemaps/googleUsersOverlay.java b/src/cgeo/geocaching/googlemaps/googleUsersOverlay.java index 5019e6e..f5f16a7 100644 --- a/src/cgeo/geocaching/googlemaps/googleUsersOverlay.java +++ b/src/cgeo/geocaching/googlemaps/googleUsersOverlay.java @@ -1,5 +1,8 @@ package cgeo.geocaching.googlemaps; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + import android.content.Context; import android.graphics.Canvas; import android.graphics.Point; @@ -15,6 +18,7 @@ import com.google.android.maps.MapView; public class googleUsersOverlay extends ItemizedOverlay<googleUsersOverlayItem> implements ItemizedOverlayImpl { private cgUsersOverlay base; + private Lock lock = new ReentrantLock(); public googleUsersOverlay(Context contextIn, Drawable markerIn) { super(boundCenter(markerIn)); @@ -91,4 +95,14 @@ public class googleUsersOverlay extends ItemizedOverlay<googleUsersOverlayItem> // Nothing to do here } -}
\ No newline at end of file + @Override + public void lock() { + lock.lock(); + } + + @Override + public void unlock() { + lock.unlock(); + } + +} diff --git a/src/cgeo/geocaching/mapcommon/cgMapOverlay.java b/src/cgeo/geocaching/mapcommon/cgMapOverlay.java index 293f0c7..d3f7c00 100644 --- a/src/cgeo/geocaching/mapcommon/cgMapOverlay.java +++ b/src/cgeo/geocaching/mapcommon/cgMapOverlay.java @@ -74,10 +74,16 @@ public class cgMapOverlay extends ItemizedOverlayBase implements OverlayBase { item.setMarker(boundCenterBottom(item.getMarker(0))); } - items = new ArrayList<CacheOverlayItemImpl>(itemsPre); - - setLastFocusedItemIndex(-1); // to reset tap during data change - populate(); + // ensure no interference between the draw and content changing routines + getOverlayImpl().lock(); + try { + items = new ArrayList<CacheOverlayItemImpl>(itemsPre); + + setLastFocusedItemIndex(-1); // to reset tap during data change + populate(); + } finally { + getOverlayImpl().unlock(); + } } public boolean getCircles() { @@ -107,51 +113,56 @@ public class cgMapOverlay extends ItemizedOverlayBase implements OverlayBase { private void drawInternal(Canvas canvas, MapProjectionImpl projection) { - if (displayCircles) { - if (blockedCircle == null) { - blockedCircle = new Paint(); - blockedCircle.setAntiAlias(true); - blockedCircle.setStrokeWidth(1.0f); - blockedCircle.setARGB(127, 0, 0, 0); - blockedCircle.setPathEffect(new DashPathEffect(new float[] {3,2}, 0)); - } - - if (setfil == null) setfil = new PaintFlagsDrawFilter(0, Paint.FILTER_BITMAP_FLAG); - if (remfil == null) remfil = new PaintFlagsDrawFilter(Paint.FILTER_BITMAP_FLAG, 0); - - canvas.setDrawFilter(setfil); - - for (CacheOverlayItemImpl item : items) { - final cgCoord itemCoord = item.getCoord(); - float[] result = new float[1]; - - Location.distanceBetween(itemCoord.latitude, itemCoord.longitude, itemCoord.latitude, itemCoord.longitude + 1, result); - final float longitudeLineDistance = result[0]; - - GeoPointImpl itemGeo = mapFactory.getGeoPointBase((int)(itemCoord.latitude * 1e6), (int)(itemCoord.longitude * 1e6)); - GeoPointImpl leftGeo = mapFactory.getGeoPointBase((int)(itemCoord.latitude * 1e6), (int)((itemCoord.longitude - 161 / longitudeLineDistance) * 1e6)); - - projection.toPixels(itemGeo, center); - projection.toPixels(leftGeo, left); - int radius = center.x - left.x; - - final String type = item.getType(); - if (type == null || "multi".equals(type) || "mystery".equals(type) || "virtual".equals(type)) { - blockedCircle.setColor(0x66000000); - blockedCircle.setStyle(Style.STROKE); - canvas.drawCircle(center.x, center.y, radius, blockedCircle); - } else { - blockedCircle.setColor(0x66BB0000); - blockedCircle.setStyle(Style.STROKE); - canvas.drawCircle(center.x, center.y, radius, blockedCircle); - - blockedCircle.setColor(0x44BB0000); - blockedCircle.setStyle(Style.FILL); - canvas.drawCircle(center.x, center.y, radius, blockedCircle); + // prevent content changes + getOverlayImpl().lock(); + try { + if (displayCircles) { + if (blockedCircle == null) { + blockedCircle = new Paint(); + blockedCircle.setAntiAlias(true); + blockedCircle.setStrokeWidth(1.0f); + blockedCircle.setARGB(127, 0, 0, 0); + blockedCircle.setPathEffect(new DashPathEffect(new float[] {3,2}, 0)); } + + if (setfil == null) setfil = new PaintFlagsDrawFilter(0, Paint.FILTER_BITMAP_FLAG); + if (remfil == null) remfil = new PaintFlagsDrawFilter(Paint.FILTER_BITMAP_FLAG, 0); + + canvas.setDrawFilter(setfil); + + for (CacheOverlayItemImpl item : items) { + final cgCoord itemCoord = item.getCoord(); + float[] result = new float[1]; + + Location.distanceBetween(itemCoord.latitude, itemCoord.longitude, itemCoord.latitude, itemCoord.longitude + 1, result); + final float longitudeLineDistance = result[0]; + + GeoPointImpl itemGeo = mapFactory.getGeoPointBase((int)(itemCoord.latitude * 1e6), (int)(itemCoord.longitude * 1e6)); + GeoPointImpl leftGeo = mapFactory.getGeoPointBase((int)(itemCoord.latitude * 1e6), (int)((itemCoord.longitude - 161 / longitudeLineDistance) * 1e6)); + + projection.toPixels(itemGeo, center); + projection.toPixels(leftGeo, left); + int radius = center.x - left.x; + + final String type = item.getType(); + if (type == null || "multi".equals(type) || "mystery".equals(type) || "virtual".equals(type)) { + blockedCircle.setColor(0x66000000); + blockedCircle.setStyle(Style.STROKE); + canvas.drawCircle(center.x, center.y, radius, blockedCircle); + } else { + blockedCircle.setColor(0x66BB0000); + blockedCircle.setStyle(Style.STROKE); + canvas.drawCircle(center.x, center.y, radius, blockedCircle); + + blockedCircle.setColor(0x44BB0000); + blockedCircle.setStyle(Style.FILL); + canvas.drawCircle(center.x, center.y, radius, blockedCircle); + } + } + canvas.setDrawFilter(remfil); } - - canvas.setDrawFilter(remfil); + } finally { + getOverlayImpl().unlock(); } } @@ -170,7 +181,22 @@ public class cgMapOverlay extends ItemizedOverlayBase implements OverlayBase { } waitDialog.show(); - CacheOverlayItemImpl item = items.get(index); + CacheOverlayItemImpl item = null; + + // prevent concurrent changes + getOverlayImpl().lock(); + try { + if (index < items.size()) { + item = items.get(index); + } + } finally { + getOverlayImpl().unlock(); + } + + if (item == null) { + return false; + } + cgCoord coordinate = item.getCoord(); if (coordinate.type != null && coordinate.type.equalsIgnoreCase("cache") && coordinate.geocode != null && coordinate.geocode.length() > 0) { diff --git a/src/cgeo/geocaching/mapinterfaces/OverlayImpl.java b/src/cgeo/geocaching/mapinterfaces/OverlayImpl.java index bd5b8ef..ba45532 100644 --- a/src/cgeo/geocaching/mapinterfaces/OverlayImpl.java +++ b/src/cgeo/geocaching/mapinterfaces/OverlayImpl.java @@ -12,5 +12,9 @@ public interface OverlayImpl { PositionOverlay, ScaleOverlay } + + void lock(); + + void unlock(); } diff --git a/src/cgeo/geocaching/mapsforge/mfCacheOverlay.java b/src/cgeo/geocaching/mapsforge/mfCacheOverlay.java index 6333133..1e3b287 100644 --- a/src/cgeo/geocaching/mapsforge/mfCacheOverlay.java +++ b/src/cgeo/geocaching/mapsforge/mfCacheOverlay.java @@ -1,5 +1,8 @@ package cgeo.geocaching.mapsforge; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + import org.mapsforge.android.maps.ItemizedOverlay; import org.mapsforge.android.maps.Projection; @@ -17,6 +20,7 @@ import cgeo.geocaching.mapinterfaces.MapViewImpl; public class mfCacheOverlay extends ItemizedOverlay<mfCacheOverlayItem> implements ItemizedOverlayImpl { private cgMapOverlay base; + private Lock lock = new ReentrantLock(); public mfCacheOverlay(cgSettings settingsIn, Context contextIn, Drawable markerIn, Boolean fromDetailIn) { super(boundCenterBottom(markerIn)); @@ -94,5 +98,15 @@ public class mfCacheOverlay extends ItemizedOverlay<mfCacheOverlayItem> implemen super.drawOverlayBitmap(canvas, drawPosition, (Projection) projection.getImpl(), drawZoomLevel); } + @Override + public void lock() { + lock.lock(); + } + + @Override + public void unlock() { + lock.unlock(); + } + } diff --git a/src/cgeo/geocaching/mapsforge/mfOverlay.java b/src/cgeo/geocaching/mapsforge/mfOverlay.java index 833d382..f764c6b 100644 --- a/src/cgeo/geocaching/mapsforge/mfOverlay.java +++ b/src/cgeo/geocaching/mapsforge/mfOverlay.java @@ -1,5 +1,8 @@ package cgeo.geocaching.mapsforge; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + import org.mapsforge.android.maps.Overlay; import org.mapsforge.android.maps.Projection; @@ -15,6 +18,7 @@ import cgeo.geocaching.mapinterfaces.OverlayImpl; public class mfOverlay extends Overlay implements OverlayImpl { private OverlayBase overlayBase = null; + private Lock lock = new ReentrantLock(); public mfOverlay(Activity activityIn, cgSettings settingsIn, OverlayImpl.overlayType ovlType) { @@ -39,4 +43,14 @@ public class mfOverlay extends Overlay implements OverlayImpl { public OverlayBase getBase() { return overlayBase; } + + @Override + public void lock() { + lock.lock(); + } + + @Override + public void unlock() { + lock.unlock(); + } } diff --git a/src/cgeo/geocaching/mapsforge/mfUsersOverlay.java b/src/cgeo/geocaching/mapsforge/mfUsersOverlay.java index 8f3ba04..6e2819c 100644 --- a/src/cgeo/geocaching/mapsforge/mfUsersOverlay.java +++ b/src/cgeo/geocaching/mapsforge/mfUsersOverlay.java @@ -1,5 +1,8 @@ package cgeo.geocaching.mapsforge; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + import org.mapsforge.android.maps.ItemizedOverlay; import org.mapsforge.android.maps.Projection; @@ -15,6 +18,7 @@ import cgeo.geocaching.mapinterfaces.MapViewImpl; public class mfUsersOverlay extends ItemizedOverlay<mfUsersOverlayItem> implements ItemizedOverlayImpl { private cgUsersOverlay base; + private Lock lock = new ReentrantLock(); public mfUsersOverlay(Context contextIn, Drawable markerIn) { super(boundCenter(markerIn)); @@ -94,4 +98,14 @@ public class mfUsersOverlay extends ItemizedOverlay<mfUsersOverlayItem> implemen super.drawOverlayBitmap(canvas, drawPosition, (Projection) projection.getImpl(), drawZoomLevel); } + @Override + public void lock() { + lock.lock(); + } + + @Override + public void unlock() { + lock.unlock(); + } + }
\ No newline at end of file |
