Как обновить элементы наложения MapView из AsyncTask без ArrayIndexOutOfBoundsException - PullRequest
3 голосов
/ 05 января 2012

Я использую MapView, которому нужно добавить несколько элементов наложения.Я считаю, что добавление элементов наложения происходит медленно и вызывает перетаскивание карты в ANR.Поэтому я создал AsyncTask для добавления элементов наложения.Первоначально я обнаружил, что это не удалось последовательно, так как я обращался к коллекции наложений из фонового потока, и я понял, что это не безопасно для потока.Поэтому я изменил его, чтобы пометки менялись только из потока пользовательского интерфейса.Это сейчас работает, но только большую часть времени.Он по-прежнему очень редко падает при касании карты.

Вот AsyncTask (внутренний класс внутри моего подкласса 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();
}


}

Вот трассировка стека:

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)

Я иду по неверному пути с AsyncTask?Если нет, можете ли вы понять, почему я получаю это исключение, когда все изменения наложений вносятся в поток пользовательского интерфейса?

Ответы [ 2 ]

0 голосов
/ 18 июля 2012

Хотя onProgressUpdate() работает в потоке пользовательского интерфейса Я не уверен, стоит ли его использовать для добавления элементов наложения.Вместо этого я рекомендую добавить оверлей в onPostExecute().Операция add () не дорогая, поскольку список элементов уже сгенерирован на данный момент.

@Override
protected void onPostExecute(List<OverlayItem> overlay) {
  mMapView.getOverlays().add(overlay);
  mMapView.invalidate();
}

Вам необходимо изменить свою подпись AsyncTask на AsyncTask<Void, User, List<OverlayItem>>, чтобысопоставьте метод.

0 голосов
/ 05 января 2012

Я думаю, вы должны вызвать postInvaliadate () представления карты после обновления наложений (после availableItemsOverlay.addOverlay(marker)).

...