I am using a MapView which needs a number of overlay items added to it. I'm finding adding the overlay items is slow and causes the map to ANR when dragged. So I built an AsyncTask to add the overlay items. Initially I found it failed consistently as I was accessing the overlay collection from a background thread, and I gather it is not thread safe. So I changed it so the overlays are only changed from the UI thread. It now works, but only most of the time. It still crashes very occasionally when the map is touched.
Here's the AsyncTask (an inner class inside my subclass of MapView):
class showItemsTask extends AsyncTask<Void, User, Void> {
public boolean stop = false;
@Override
protected void onPreExecute() {
super.onPreExecute();
}
protected Void doInBackground(Void... v) {
User[] items = Item.getItemList();
if (items != null && items.length > 0) {
int i = 0;
for (User item : items) {
publishProgress(item);
i++;
if (stop || i>MAX_NUMBER_OF_ITEMS) break;
}
stop = false;
}
return null;
}
@Override
protected void onProgressUpdate(User... itemContainer) {
super.onProgressUpdate(itemContainer);
User item = itemContainer[0];
showItem(item.location.latitude, item.location.longitude, item.location.firstname, ((Integer) item.location.id).toString());
}
public void showItem(float latitude, float longitude, String itemTitle, String itemSubtitle) {
try {
GeoPoint point = new GeoPoint((int) (latitude * 1000000), (int) (longitude * 1000000));
OverlayItem marker = new OverlayItem(point, itemTitle, itemSubtitle);
availableItemsOverlay.addOverlay(marker);
} catch (Exception e) {
Trace.e(TAG, "Exception drawing a item");
}
}
protected void onPostExecute(Void v) {
invalidate();
}
}
Here's the stack trace:
0 java.lang.ArrayIndexOutOfBoundsException
1 at com.google.android.maps.ItemizedOverlay.maskHelper(ItemizedOverlay.java:562)
2 at com.google.android.maps.ItemizedOverlay.setFocus(ItemizedOverlay.java:365)
3 at com.google.android.maps.ItemizedOverlay.focus(ItemizedOverlay.java:539)
4 at com.google.android.maps.ItemizedOverlay.onTap(ItemizedOverlay.java:455)
5 at com.google.android.maps.OverlayBundle.onTap(OverlayBundle.java:83)
Am I going down the wrong path with AsyncTask? If not, can you see why I'm getting this exception, when all changes to overlays are being made in the UI thread?
I think you must call postInvaliadate() of map view after updating overlays (after availableItemsOverlay.addOverlay(marker)
).
Although onProgressUpdate()
runs on the UI thread I am not sure if it is ment to be used to add overlay items. Instead, I recommend to add the overlay in onPostExecute()
. The add() operation is not expensive since the list of items has already been generated at this point in time.
@Override
protected void onPostExecute(List<OverlayItem> overlay) {
mMapView.getOverlays().add(overlay);
mMapView.invalidate();
}
You need to change the signature of you AsyncTask
to AsyncTask<Void, User, List<OverlayItem>>
in order to match the method.
来源:https://stackoverflow.com/questions/8744573/how-to-update-mapview-overlay-items-from-an-asynctask-without-arrayindexoutofbou