zooming后arrayindexoutofbound mapview

zooming后arrayindexoutofbound mapview

问题描述:

我的地图应用程序出现问题。我正在填充asynctask中的地图叠加层。它们被添加到ui线程的mapview中。zooming后arrayindexoutofbound mapview

当我缩放地图并在之后添加新点时会发生问题,这会触发这些要显示的点的计算。无论何时执行此模式(打开地图,缩放,添加点),我都会在android类方法viewroot.draw内获得arrayindexoutofboundsexception

添加所有点后,填充的asynctask也会在我的itemized_overlay实现上调用populate()。这是doinbackground-method返回,然后我立即得到提到的异常。它不运行onpostexecution-method,应该遵循。如果mapview没有被触及,我可以添加尽可能多的点数。发生错误时,覆盖图标会在调试器停止应用程序之前消失,除了它们的阴影。

Thread [<1> main] (Suspended (exception ArrayIndexOutOfBoundsException))  
    ViewRoot.draw(boolean) line: 1457  
    ViewRoot.performTraversals() line: 1167  
    ViewRoot.handleMessage(Message) line: 1764  
    ViewRoot(Handler).dispatchMessage(Message) line: 99  
    Looper.loop() line: 143  
    ActivityThread.main(String[]) line: 5068  
    Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method]  
    Method.invoke(Object, Object...) line: 521  
    ZygoteInit$MethodAndArgsCaller.run() line: 858  
    ZygoteInit.main(String[]) line: 616  
    NativeStart.main(String[]) line: not available [native method] 

任何想法?

编辑:添加代码

中的AsyncTask:

private void dbAbfrageStarten() { 

     SQLiteDatabase sqldb_zugriff = sqldb_db_verwaltung 
       .getReadableDatabase(); 

     // select * from tabellenname where zeit>x 
     Cursor cursor_db_anfrage_geopkt = sqldb_zugriff.query(
       SQL_DB_Verwaltung.TABELLEN_NAME, 
       null, 
       "zeit >" 
         + Long.toString(memosingleton_anwendung 
           .letzterDBZugriff(MemoSingleton.KARTE)), null, 
       null, null, null); 

     // select icon from tabellenname groupby icon 
     // erfasse symbole die den ausgelesenen punkten zugeordnet wurden 
     Cursor cursor_db_anfrage_icon = sqldb_zugriff.query(
       SQL_DB_Verwaltung.TABELLEN_NAME, 
       new String[] { SQL_DB_Verwaltung.NAME_SPALTE_5 }, null, null, 
       SQL_DB_Verwaltung.NAME_SPALTE_5, null, null); 

     PunkteZeigen_Tab_AsyncTask asynctask_dbabfrage = new PunkteZeigen_Tab_AsyncTask(
       this, PunkteZeigen_Tab_AsyncTask.KARTE); 

     asynctask_dbabfrage.execute(cursor_db_anfrage_geopkt, 
       cursor_db_anfrage_icon); 

     Log.d("memo_debug", "dbAbfrageStarten fertig"); 
    } 

    public void karteAnzeigen(
      HashMap<Integer, ItemOverlay_neu> hashmap_itemoverlays_temp, 
      int int_modus) { 

     Log.d("memo_debug", "karteAnzeigen punkt1"); 

     // erfasse, zur zeit auf der karte angezeigte, overlays 
     MapView mapview_karte = (MapView) this 
       .findViewById(R.id.punktezeigen_karte_layout_mapview_neu); 

     List<Overlay> list_karten_overlay = mapview_karte.getOverlays(); 

     memosingleton_anwendung.aktualisiereDBZugriff(MemoSingleton.KARTE); 

     Iterator<ItemOverlay_neu> iterator_itemoverlays; 

     Log.d("memo_debug", "karteAnzeigen punkt2"); 

     switch (int_modus) { 
     case ANZEIGEN: 
      iterator_itemoverlays = hashmap_itemoverlays_temp.values() 
        .iterator(); 
      break; 
     case WIEDERHERSTELLEN: 
      iterator_itemoverlays = memosingleton_anwendung.hashmap_itemoverlays 
        .values().iterator(); 
      break; 
     default: 
      iterator_itemoverlays = null; 
     } 

     Log.d("memo_debug", "karteAnzeigen punkt3"); 

     while ((iterator_itemoverlays != null) 
       && iterator_itemoverlays.hasNext()) { 
      list_karten_overlay.add(iterator_itemoverlays.next()); 
     } 

     // zeichne die karte neu 
     mapview_karte.invalidate(); 

     Log.d("memo_debug", "karteAnzeigen fertig"); 
    } 

memosingleton_anwendung是应用程序的实例,其中i存储:是启动的AsyncTask,并把它称为完成后

package de.***.android.memo_neu; 

import java.util.HashMap; 
import java.util.Iterator; 

import android.app.ProgressDialog; 
import android.content.Context; 
import android.database.Cursor; 
import android.os.AsyncTask; 
import android.util.Log; 

import com.google.android.maps.OverlayItem; 

public class PunkteZeigen_Tab_AsyncTask extends 
     AsyncTask<Cursor, Integer, Object> { 

    private PunkteZeigen_Tab_Liste context_liste; 
    private PunkteZeigen_Tab_Karte context_karte; 
    private ProgressDialog progress_fortschritt; 
    private int int_modus; 

    public static final int LISTE = 0; 
    public static final int KARTE = 1; 
    private static final int PROGRESS_SET_MIN = 0; 
    private static final int PROGRESS_UPDATE = 1; 
    private static final int PROGRESS_SET_MAX = 2; 
    private static final int PROGRESS_MAX = 3; 

    public PunkteZeigen_Tab_AsyncTask(Object con, int int_mod) { 
     int_modus = int_mod; 

     switch (int_modus) { 
     case LISTE: 
      context_liste = (PunkteZeigen_Tab_Liste) con; 
      break; 
     case KARTE: 
      context_karte = (PunkteZeigen_Tab_Karte) con; 
      break; 
     default: 
     } 
    } 

    protected void onPreExecute() { 

     switch (int_modus) { 
     case LISTE: 
      progress_fortschritt = new ProgressDialog((Context) context_liste); 
      progress_fortschritt 
        .setTitle(R.string.punktezeigen_tab_liste_asynctask_progressdialog_title); 
      break; 
     case KARTE: 
      progress_fortschritt = new ProgressDialog((Context) context_karte); 
      progress_fortschritt 
        .setTitle(R.string.punktezeigen_tab_karte_asynctask_progressdialog_title); 
      break; 
     default: 
     } 

     progress_fortschritt.setCancelable(false); 
     progress_fortschritt.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); 

     progress_fortschritt.show(); 

     Log.d("memo_debug", "onPreExecute fertig"); 
    } 

    protected void onProgressUpdate(Integer... int_progress) { 

     switch (int_progress[0]) { 
     case PROGRESS_SET_MIN: 
      progress_fortschritt.setProgress(int_progress[1]); 
      break; 
     case PROGRESS_UPDATE: 
      if (int_progress[1] >= 0) { 

       if ((int_progress[1] % 5) == 0) { 
        progress_fortschritt 
          .incrementProgressBy(progress_fortschritt.getMax()/5); 
       } 

      } else { 
       progress_fortschritt.incrementProgressBy(-int_progress[1]); 
      } 
      break; 
     case PROGRESS_SET_MAX: 
      progress_fortschritt.setMax(int_progress[1]); 
      break; 
     case PROGRESS_MAX: 
      progress_fortschritt.setProgress(progress_fortschritt.getMax()); 
      break; 
     default: 
     } 
    } 

    protected Object doInBackground(Cursor... cursor_db_anfrage) { 

     progress_fortschritt.setMax(cursor_db_anfrage[0].getCount()); 

     switch (int_modus) { 
     case LISTE: 
      return listeBearbeiten(cursor_db_anfrage[0]); 
     case KARTE: 
      return karteBearbeiten(cursor_db_anfrage); 
     default: 
      return -1; 
     } 

    } 

    private int listeBearbeiten(Cursor cursor_db_anfrage) { 

     if (cursor_db_anfrage.moveToFirst()) { 

      GeoPunkt geopkt_geopunkt = new GeoPunkt(); 
      HashMap<String, Object> hashmap_liste_daten_datum; 

      do { 
       // geopkt_geopunkt.id= cursor_db_anfrage.getInt(0); 
       geopkt_geopunkt.name = cursor_db_anfrage.getString(1); 
       geopkt_geopunkt.lat = cursor_db_anfrage.getInt(2); 
       geopkt_geopunkt.lon = cursor_db_anfrage.getInt(3); 
       geopkt_geopunkt.icon = cursor_db_anfrage.getInt(4); 

       hashmap_liste_daten_datum = new HashMap<String, Object>(2); 
       hashmap_liste_daten_datum.put("geopkt_name", 
         geopkt_geopunkt.name); 
       hashmap_liste_daten_datum.put("geopkt_lat_lon", "Lat:" 
         + Integer.toString(geopkt_geopunkt.lat) + " " + "Lon:" 
         + Integer.toString(geopkt_geopunkt.lon)); 
       hashmap_liste_daten_datum.put("geopkt_icon", 
         geopkt_geopunkt.icon); 

       context_liste.memosingleton_anwendung.list_liste_daten 
         .add(hashmap_liste_daten_datum); 

       publishProgress(PROGRESS_UPDATE, 
         cursor_db_anfrage.getPosition()); 

      } while (cursor_db_anfrage.moveToNext()); 

     } 

     return cursor_db_anfrage.getCount(); 
    } 

    private HashMap<Integer, ItemOverlay_neu> karteBearbeiten(
      Cursor... cursor_db_anfrage) { 

     // cursor_db_anfrage[0] geopkt, cursor_db_anfrage[1] icon 

     // temporaere hashmap fuer overlays (sammlung von punkten) die der 
     // karte hinzugefuegt werden. 
     HashMap<Integer, ItemOverlay_neu> hashmap_itemoverlays_temp = new HashMap<Integer, ItemOverlay_neu>(); 

     // falls neue punkte vorhanden sind 
     if (cursor_db_anfrage[0].moveToFirst()) { 

      ItemOverlay_neu itemoverlay_temp; 

      GeoPunkt geopkt_geopunkt = new GeoPunkt(); 

      OverlayItem overlayitem_temp; 

      // fuer alle gefundenen symbole 
      if (cursor_db_anfrage[1].moveToFirst()) { 

       do { 

        // erzeuge overlay mit zugeordnetem symbol 
        itemoverlay_temp = new ItemOverlay_neu(context_karte 
          .getResources().getDrawable(
            cursor_db_anfrage[1].getInt(0)), 
          context_karte); 

        // falls in der hashmap des singletons noch kein overlay mit 
        // diesem symbol vorhanden ist, fuege es hinzu 
        if (!context_karte.memosingleton_anwendung.hashmap_itemoverlays 
          .containsKey(cursor_db_anfrage[1].getInt(0))) { 
         context_karte.memosingleton_anwendung.hashmap_itemoverlays 
           .put(cursor_db_anfrage[1].getInt(0), 
             itemoverlay_temp); 
        } 

        // fuege das overlay in die temporaere hashmap ein 
        hashmap_itemoverlays_temp.put(
          cursor_db_anfrage[1].getInt(0), itemoverlay_temp); 

        // hashmap aus dem singleton speichert alle overlays mit den 
        // entsprechenden geopunkten, temporaere hashmap speichert 
        // nur neue geopunkte 
       } while (cursor_db_anfrage[1].moveToNext()); 
      } 

      Log.d("memo_debug", "erste while do fertig"); 

      // fuer alle erfassten neuen punkte 
      do { 
       // geopkt_geopunkt.id = cursor_db_anfrage.getInt(0); 
       geopkt_geopunkt.name = cursor_db_anfrage[0].getString(1); 
       geopkt_geopunkt.lat = cursor_db_anfrage[0].getInt(2); 
       geopkt_geopunkt.lon = cursor_db_anfrage[0].getInt(3); 
       geopkt_geopunkt.icon = cursor_db_anfrage[0].getInt(4); 

       // erzeuge overlayitem (geopunkt mit zusaetzlichen daten) zum 
       // einfuegen in overlays 

       overlayitem_temp = new OverlayItem(
         geopkt_geopunkt.getGeoPoint(), geopkt_geopunkt.name, ""); 

       // fuege neue punkte zur singleton hashmap und zur temporaeren 
       // hashmap hinzu 
       itemoverlay_temp = context_karte.memosingleton_anwendung.hashmap_itemoverlays 
         .get(geopkt_geopunkt.icon); 
       itemoverlay_temp.addOverlay(overlayitem_temp); 

       itemoverlay_temp = hashmap_itemoverlays_temp 
         .get(geopkt_geopunkt.icon); 
       itemoverlay_temp.addOverlay(overlayitem_temp); 

       publishProgress(PROGRESS_UPDATE, 
         cursor_db_anfrage[0].getPosition()); 

      } while (cursor_db_anfrage[0].moveToNext()); 

      Log.d("memo_debug", "zweite while do fertig"); 

      publishProgress(PROGRESS_MAX, 0); 

      // ruft populate() fuer die overlays auf, um sie spaeter anzeigen zu 
      // koennen 
      Iterator<ItemOverlay_neu> iterator_itemoverlays = context_karte.memosingleton_anwendung.hashmap_itemoverlays 
        .values().iterator(); 

      publishProgress(PROGRESS_SET_MIN, 0); 
      publishProgress(PROGRESS_SET_MAX, 
        context_karte.memosingleton_anwendung.hashmap_itemoverlays 
          .size()); 

      while (iterator_itemoverlays.hasNext()) { 
       iterator_itemoverlays.next().initialisieren(); 
       publishProgress(PROGRESS_UPDATE, -1); 
      } 

      Log.d("memo_debug", "erstes populate fertig"); 

      publishProgress(PROGRESS_MAX, 0); 

      iterator_itemoverlays = hashmap_itemoverlays_temp.values() 
        .iterator(); 

      publishProgress(PROGRESS_SET_MIN, 0); 
      publishProgress(PROGRESS_SET_MAX, hashmap_itemoverlays_temp.size()); 

      while (iterator_itemoverlays.hasNext()) { 
       iterator_itemoverlays.next().initialisieren(); 
       publishProgress(PROGRESS_UPDATE, -1); 
      } 

      Log.d("memo_debug", "zweites populate fertig"); 

      publishProgress(PROGRESS_MAX, 0); 
     } 

     Log.d("memo_debug", "karteBearbeiten fertig"); 

     return hashmap_itemoverlays_temp; 

    } 

    protected void onPostExecute(Object obj_result) { 

     Log.d("memo_debug", "onPostExecute gestartet"); 

     switch (int_modus) { 
     case LISTE: 
      context_liste.listeAnzeigen((Integer) obj_result); 
      break; 
     case KARTE: 
      context_karte.karteAnzeigen(
        (HashMap<Integer, ItemOverlay_neu>) obj_result, 
        PunkteZeigen_Tab_Karte.ANZEIGEN); 
      break; 
     default: 
     } 

     progress_fortschritt.setProgress(progress_fortschritt.getMax()); 
     progress_fortschritt.dismiss(); 

     Log.d("memo_debug", "onPostExecute fertig"); 
    } 
} 

方法一些数据。

编辑进一步调查:

我进一步研究这个问题,似乎从使用memosingleton_anwendung.hashmap_itemoverlays的发起。如果我不添加点这些覆盖,应用程序完美无瑕。看起来populate()运行在一个单独的线程中,并且无法处理列表中的更改,尽管我在添加所有点后调用它。

+0

你可以发布代码吗?如果您正在访问AsyncTask中的某个数组,但将该点添加到该AsyncTask之外的其他数组中,那么显然您会得到一个OutOfBoundsException。发布你的代码,以及AsyncTask等。 – LuxuryMode

+0

@LuxuryMode补充来源 – vendetta

我的问题的解决方案包括将计算的叠加存储在ArrayList<Overlay>中,而不是存储我的ItemizedOverlay实现的对象。