2012-01-05 3 views
3

MapView를 사용하여 오버레이 항목을 추가해야합니다. 오버레이 항목을 추가하면 속도가 느려지고 끌 때지도가 ANR로 표시됩니다. 그래서 오버레이 아이템을 추가하기 위해 AsyncTask를 만들었습니다. 처음에는 배경 스레드에서 오버레이 컬렉션에 액세스 할 때 일관되게 실패하고 스레드 안전하지 않은 것을 수집합니다. 그래서 오버레이가 UI 스레드에서만 변경되도록 UI를 변경했습니다. 이제는 작동하지만 대부분의 경우에만 작동합니다. 지도가 만지면 여전히 가끔 충돌합니다.ArrayIndexOutOfBoundsException없이 AsyncTask에서 MapView 오버레이 항목을 업데이트하는 방법

여기에 AsyncTask를 (지도보기 내 서브 클래스 내의 내부 클래스)입니다 :

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를 가진 잘못된 길을 가고 있는가 : 여기

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


} 

는 스택 추적입니까? 그렇지 않다면 UI 스레드에서 오버레이에 대한 모든 변경이 이루어질 때 왜이 예외가 발생하는지 알 수 있습니까?

+0

mapView가 무효화되지 않는 정확한 이유를 알고 계셨습니까? 비슷한 문제가 있습니다. http : //stackoverflow.com/questions/23011264/mapview-doesnt-invalidate-onprogressupdated-of-async-task – zIronManBox

답변

0

오버레이를 업데이트 한 후지도보기의 postInvaliadate()를 호출해야한다고 생각합니다 (availableItemsOverlay.addOverlay(marker) 이후).

0

onProgressUpdate()runs on the UI thread 오버레이 항목을 추가하는 데 사용할지 여부는 확실하지 않습니다. 대신 onPostExecute()에 오버레이를 추가하는 것이 좋습니다. add() 작업은 항목 목록이이 시점에서 이미 생성되었으므로 비용이 많이 들지 않습니다.

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

당신은 방법과 일치하기 위해 AsyncTask<Void, User, List<OverlayItem>>AsyncTask의 서명을 변경해야합니다.

+0

다음을 살펴볼 수도 있습니다 : http : //stackoverflow.com/questions/23011264/mapview-doesnt-invalidate-onprogressupdated-async-task 비슷한 문제가 있습니다. – zIronManBox

관련 문제