2011-11-24 25 views
6

使用com.google.android.maps API,我得到了MapActivity,它使用ItemizedOverlayMapView上放置了多個(最多約1000個)圖標。當LocationListener檢測到設備移動了一定距離(當前爲5米,但僅用於測試)時,我想刷新(或者只是添加到圖標列表中)圖標。刷新地圖ItemizedOverlay給出ArrayIndexOutOfBoundsException

我已經添加了setLastFocusedIndex(-1)populate(),但是我的ItemizedOverlay仍然崩潰。 我認爲當我向列表中添加更多項目時會崩潰,但有時即使我不移動手機,它似乎也會崩潰。它在第一次更新時崩潰。我無法從LogCat中知道觸發錯誤的原因。

我MapActivity是基於關閉各種教程:

編輯:調整了代碼做一個batch update of items但它仍然崩潰

public class NearbyActivity extends MapActivity implements VenueCatalogListener { 
    private final String TAG = this.getClass().getSimpleName(); 

    List<Overlay> mapOverlays; 
    HelloItemizedOverlay itemizedOverlay; 

    private MapController mapController; 
    private MapView mapView; 
    private LocationManager locationManager; 

    private int latE6; 
    private int lonE6; 

    private Location current_location; 
    private VenuesFromServer venues_from_server; 

    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     venues_from_server = new VenuesFromServer(this); 
     setupViews(); 
    } 

    private void setupViews() { 
     setContentView(R.layout.nearby_view); 


     RelativeLayout linearLayout = (RelativeLayout) findViewById(R.id.mapMainLayout); 

     mapView = new MapView(this, PreferencesManager.CLUBBERIA_MAPS_API_KEY); 
     initializeMap(); 

     linearLayout.addView(mapView); 
    } 

    private void initializeMap() { 
     mapView.setKeepScreenOn(true); 
     mapView.setClickable(true); 
     mapView.setBuiltInZoomControls(true); 
     mapController = mapView.getController(); 
     mapController.setZoom(mapView.getMaxZoomLevel()-5); // Zoom 1 is world view 

     locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); 
     locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, new GeoUpdateHandler()); 

     mapOverlays = mapView.getOverlays(); 
     if(itemizedOverlay == null) { 
      Drawable drawable = this.getResources().getDrawable(R.drawable.icon); 
      itemizedOverlay = new HelloItemizedOverlay(drawable); 
      mapOverlays.add(itemizedOverlay); 
     } 
    } 

    @Override 
    protected boolean isRouteDisplayed() { 
     return false; 
    } 

    public class GeoUpdateHandler implements LocationListener { 
     @Override 
     public void onLocationChanged(Location location) { 
      if(current_location == null) { 
       current_location = location; 
      } 

      int lat = (int) (location.getLatitude() * 1E6); 
      int lng = (int) (location.getLongitude() * 1E6); 
      GeoPoint point = new GeoPoint(lat, lng); 
      if(current_location.distanceTo(location) > 5) { 
       // this kicks off an async task that will call back to venueListUpdated() below 
       venues_from_server.getVenueJSONFromServer(location.getLatitude(), location.getLongitude(), 19); 
      } 
      mapController.animateTo(point); // mapController.setCenter(point); 
     } 

     @Override 
     public void onProviderDisabled(String provider) { 
     } 

     @Override 
     public void onProviderEnabled(String provider) { 
     } 

     @Override 
     public void onStatusChanged(String provider, int status, Bundle extras) { 
     } 
    } 

    @Override 
    public void venueListUpdated() { 

     // Base.B.arrayVenuesMap is an ArrayList<Venue> 
     for(int i=0;i<Base.B.arrayVenuesMap.size();i++) { 
      Venue _venue = Base.B.arrayVenuesMap.get(i); 
      latE6 = (int) (_venue.latitude*1e6); 
      lonE6 = (int) (_venue.longitude*1e6); 
      GeoPoint point = new GeoPoint(latE6, lonE6); 
      OverlayItem overlayitem = new OverlayItem(point, _venue.name, ""); 
      Drawable drawable = this.getResources().getDrawable(R.drawable.icon); 

      itemizedOverlay.addOverlay(overlayitem, drawable); 
     } 
     itemizedOverlay.batchPopulate(); 
    } 
} 

我的ItemizedOverlay看起來是這樣的:

public class HelloItemizedOverlay extends ItemizedOverlay<OverlayItem> { 

    private ArrayList<OverlayItem> mOverlays = null; 

    public HelloItemizedOverlay(Drawable defaultMarker) { 
     super(boundCenterBottom(defaultMarker)); 
     mOverlays = new ArrayList<OverlayItem>(); 
     setLastFocusedIndex(-1); 
     populate(); 
    } 

    public void addOverlay(OverlayItem overlay, Drawable defaultMarker) { 
     if(!mOverlays.contains(overlay)) { 
      setLastFocusedIndex(-1); 
      overlay.setMarker(boundCenterBottom(defaultMarker)); 
      mOverlays.add(overlay); 
     } 
    } 

    public void batchPopulate() { 
     setLastFocusedIndex(-1); 
     populate(); 
    } 

    @Override 
    protected OverlayItem createItem(int i) { 
     return mOverlays.get(i); 
    } 

    @Override 
    public int size() { 
     return mOverlays.size(); 
    } 
} 

Logcat具有以下幾行:

11-24 18:28:02.245: D/AsyncJSONClient(18382): starting connect with this many pairs: 0; thread 17 
11-24 18:28:02.255: E/AndroidRuntime(18382): FATAL EXCEPTION: main 
11-24 18:28:02.255: E/AndroidRuntime(18382): java.lang.ArrayIndexOutOfBoundsException 
11-24 18:28:02.255: E/AndroidRuntime(18382): at com.google.android.maps.ItemizedOverlay.getIndexToDraw(ItemizedOverlay.java:211) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at com.google.android.maps.ItemizedOverlay.draw(ItemizedOverlay.java:240) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at com.google.android.maps.Overlay.draw(Overlay.java:179) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at com.google.android.maps.OverlayBundle.draw(OverlayBundle.java:42) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at com.google.android.maps.MapView.onDraw(MapView.java:530) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.View.draw(View.java:6918) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.drawChild(ViewGroup.java:1646) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.drawChild(ViewGroup.java:1644) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.View.draw(View.java:6921) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.widget.FrameLayout.draw(FrameLayout.java:357) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.drawChild(ViewGroup.java:1646) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.drawChild(ViewGroup.java:1644) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.drawChild(ViewGroup.java:1644) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.drawChild(ViewGroup.java:1644) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.drawChild(ViewGroup.java:1644) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.View.draw(View.java:6921) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.widget.FrameLayout.draw(FrameLayout.java:357) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.drawChild(ViewGroup.java:1646) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.View.draw(View.java:6921) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.widget.FrameLayout.draw(FrameLayout.java:357) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1947) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewRoot.draw(ViewRoot.java:1539) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewRoot.performTraversals(ViewRoot.java:1275) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.view.ViewRoot.handleMessage(ViewRoot.java:1876) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.os.Handler.dispatchMessage(Handler.java:99) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.os.Looper.loop(Looper.java:123) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at android.app.ActivityThread.main(ActivityThread.java:3728) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at java.lang.reflect.Method.invokeNative(Native Method) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at java.lang.reflect.Method.invoke(Method.java:507) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:864) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:622) 
11-24 18:28:02.255: E/AndroidRuntime(18382): at dalvik.system.NativeStart.main(Native Method) 
11-24 18:28:02.255: W/ActivityManager(308): Force finishing activity com.clubberia.android/.ClubberiaMain 

如何偶爾向ItemizedOverlay添加項目而不會崩潰?

回答

3

妮知道它有點老了,但@cgwylie差不多吧..

你應該更新疊加值後打電話populate() ...然後你可以調用postInvalidate()

0

當您更改的ItemizedOverlay項目,你需要調用postInvalidate()MapView,讓它知道你已經調整疊加,所以它不會嘗試和借鑑不在列表中再次物品。

在您的venueListUpdated()中,您可以嘗試在致電itemizedOverlay.addOverlay(overlayitem, drawable)後添加mapView.postInvalidate()來解決您的問題。

+0

哼。我剛剛嘗試了你的建議,但沒有奏效。不管怎麼說,還是要謝謝你! –

+0

很酷,很遺憾,它沒有奏效,它爲我解決了過去的問題。 – cgwyllie