我的地图应用程序出了问题。我正在填充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()
在一个单独的线程中运行,并且无法处理列表中的更改,尽管我在添加所有点后调用它。
答案 0 :(得分:1)
我的问题的解决方案包括将计算的叠加层存储在ArrayList<Overlay>
中,而不是存储我的ItemizedOverlay
的对象 - 实现。