缩放mapview后的arrayindexoutofbound

时间:2011-11-21 20:35:53

标签: android zoom android-mapview

我的地图应用程序出了问题。我正在填充asynctask内的地图叠加层。它们被添加到ui-thread中的mapview中。

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

在添加所有点后,填充的asynctask还会在populate()实现上调用itemized_overlay。它是doinbackground-method返回,然后我立即得到提到的异常。它不会运行onpostexecution-method,它应该跟随。如果没有触摸地图视图,我可以添加任意数量的点。发生错误时,覆盖图标将在调试器停止应用程序之前消失,但阴影除外。

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:

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

启动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是我存储一些数据的应用程序实例。

编辑进一步调查:

我进一步调查了这个问题,它似乎源于memosingleton_anwendung.hashmap_itemoverlays的使用。如果我没有为这些叠加添加点,那么该应用程序可以完美运行。似乎populate()在一个单独的线程中运行,并且无法处理列表中的更改,尽管我在添加所有点后调用它。

1 个答案:

答案 0 :(得分:1)

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