如何从没有ArrayIndexOutOfBoundsException异常的AsyncTask的更新的MapView覆盖项目 [英] How to update MapView overlay items from an AsyncTask without ArrayIndexOutOfBoundsException

查看:172
本文介绍了如何从没有ArrayIndexOutOfBoundsException异常的AsyncTask的更新的MapView覆盖项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的需求添​​加到它的一些覆盖项的图形页面。我发现将覆盖项目是慢拖时,导致地图ANR。所以,我建立了一个的AsyncTask添加覆盖项目。起初,我发现它始终未能因为我是从后台线程访问覆盖集合,我推测它不是线程安全的。所以我改变它,因此覆盖只能从UI线程改变。它现在的工作原理,但只大部分时间。它仍然崩溃时,地图被触摸很偶然。

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.

下面是AsyncTask的(我MapView类的子类中的内部类):

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();
}


}

下面的堆栈跟踪:

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在错误的道路?如果没有,你可以看到为什么我得到这个例外,当在UI线程被做覆盖所有更改?

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?

推荐答案

虽然 onProgressUpdate()在UI线程上运行我不知道这是否是精神疾病被用来添加叠加物品。相反,我建议增加覆盖在 onPostExecute()。因为项目的列表已经在这个时间点产生的add()操作也不贵。

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();
}

您需要的您的AsyncTask 签名更改为的AsyncTask&LT;无效,用户列表与LT; OverlayItem&GT;&GT; 为了匹配方法

You need to change the signature of you AsyncTask to AsyncTask<Void, User, List<OverlayItem>> in order to match the method.

这篇关于如何从没有ArrayIndexOutOfBoundsException异常的AsyncTask的更新的MapView覆盖项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆