この問題は私の頭を悩ませてきました、そしてあなたが助けてくれることを願っています!私は以前にここで多くの問題に対する答えを見つけました、そしてあなたの人々があなたの魔法を再び働かせることを願っています:)
さて、私のアプリの一部はGoogle Maps APIを使用して、地図上にオーバーレイを表示し(カスタムオーバーレイクラスを使用)、mylocationoverlayを使用してユーザーの場所を表示します。mylocationoverlayをアクティブにしないと、すべてが正常に機能しますが、アクティブにすると、アプリの強制は。で閉じますConcurrentModificationException
。
オーバーレイの位置は常に変化するため、タイマーを使用してオーバーレイを更新します。このために、非同期タスクを使用してオーバーレイを削除し、更新された位置で新しいオーバーレイを追加しました。mylocationoverlayがバックグラウンドで同様のことを行うと仮定するのは正しいですか?その仮定が有効である場合、mylocationoverlayと非同期タスクが同じ配列を同時に反復/変更しようとしているという結論に達しました。唯一これは、これが起こらないようにする方法がわかりません!
コードが非常に大きいため、ここに実際に投稿することはできませんが、commonsguyによって作成されたgithubから取得したサンプルコードを使用し、同じ問題が発生するように変更しました。
これは本当に私を苛立たせているので、どんな助けでも大歓迎です。事前に感謝し、長い説明をお詫びします!
編集:commonsguyコードのリンクは-https: //github.com/commonsguy/cw-advandroid/blob/master/Maps/NooYawkAsync/
編集2:Javaコードの後にエラートレースを追加しました。
package com.commonsware.android.maps;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import com.google.android.maps.MyLocationOverlay;
import com.google.android.maps.OverlayItem;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
public class NooYawk extends MapActivity {
private MapView map=null;
private MyLocationOverlay me=null;
private SitesOverlay sites=null;
public Timer timer;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
map=(MapView)findViewById(R.id.map);
map.getController().setCenter(getPoint(40.76793169992044, -73.98180484771729));
map.getController().setZoom(17);
map.setBuiltInZoomControls(true);
me=new MyLocationOverlay(this, map);
me.enableMyLocation();
map.getOverlays().add(me);
timer = new Timer();
timer.scheduleAtFixedRate(new RemindTask(), 10000, 10000);
new OverlayTask().execute();
}
@Override
public void onResume() {
super.onResume();
me.enableMyLocation();
me.enableCompass();
}
@Override
public void onPause() {
super.onPause();
me.disableMyLocation();
me.disableCompass();
}
@Override
protected boolean isRouteDisplayed() {
return(false);
}
private GeoPoint getPoint(double lat, double lon) {
return(new GeoPoint((int)(lat*1000000.0), (int)(lon*1000000.0)));
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////// TIMER CLASS //////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class RemindTask extends TimerTask {
public void run() {
new OverlayTask().execute();
}
}
private class SitesOverlay extends ItemizedOverlay<CustomItem> {
private Drawable heart=null;
private List<CustomItem> items=new ArrayList<CustomItem>();
public SitesOverlay() {
super(null);
heart=getMarker(R.drawable.heart_full);
items.add(new CustomItem(getPoint(40.748963847316034, -73.96807193756104),
"UN", "United Nations", getMarker(R.drawable.blue_full_marker), heart));
populate();
}
@Override
protected CustomItem createItem(int i) {
return(items.get(i));
}
@Override
public void draw(Canvas canvas, MapView mapView, boolean shadow) {
super.draw(canvas, mapView, shadow);
}
@Override
public int size() {
return(items.size());
}
void toggleHeart() {
CustomItem focus=getFocus();
if (focus!=null) {
focus.toggleHeart();
}
map.invalidate();
}
private Drawable getMarker(int resource) {
Drawable marker=getResources().getDrawable(resource);
marker.setBounds(0, 0, marker.getIntrinsicWidth(), marker.getIntrinsicHeight());
boundCenter(marker);
return(marker);
}
}
class PopupPanel {
View popup;
boolean isVisible=false;
PopupPanel(int layout) {
ViewGroup parent=(ViewGroup)map.getParent();
popup=getLayoutInflater().inflate(layout, parent, false);
popup.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
hide();
}
});
}
View getView() {
return(popup);
}
void show(boolean alignTop) {
RelativeLayout.LayoutParams lp=new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT
);
if (alignTop) {
lp.addRule(RelativeLayout.ALIGN_PARENT_TOP);
lp.setMargins(0, 20, 0, 0);
}
else {
lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
lp.setMargins(0, 0, 0, 60);
}
hide();
((ViewGroup)map.getParent()).addView(popup, lp);
isVisible=true;
}
void hide() {
if (isVisible) {
isVisible=false;
((ViewGroup)popup.getParent()).removeView(popup);
}
}
}
class CustomItem extends OverlayItem {
Drawable marker=null;
boolean isHeart=false;
Drawable heart=null;
CustomItem(GeoPoint pt, String name, String snippet, Drawable marker, Drawable heart) {
super(pt, name, snippet);
this.marker=marker;
this.heart=heart;
}
@Override
public Drawable getMarker(int stateBitset) {
Drawable result=(isHeart ? heart : marker);
setState(result, stateBitset);
return(result);
}
void toggleHeart() {
isHeart=!isHeart;
}
}
class OverlayTask extends AsyncTask<Void, Void, Void> {
@Override
public void onPreExecute() {
if (sites!=null) {
map.getOverlays().remove(sites);
map.postInvalidate();
sites=null;
}
}
@Override
public Void doInBackground(Void... unused) {
//SystemClock.sleep(5000); // simulated work
sites=new SitesOverlay();
return(null);
}
@Override
public void onPostExecute(Void unused) {
map.getOverlays().add(sites);
map.postInvalidate();
}
}
}
スタックトレース:
java.util.ConcurrentModificationException at java.util.ArrayList $ ArrayListIterator.next(ArrayList.java:573)at com.google.android.maps.OverlayBundle.draw(OverlayBundle.java:44)atcom.google.android.maps。 MapView.onDraw(MapView.java:494)at android.view.View.draw(View.java:6740)at android.view.ViewGroup.drawChild(ViewGroup.java:1640)at android.view.ViewGroup.dispatchDraw(ViewGroup .java:1367)at android.view.ViewGroup.drawChild(ViewGroup.java:1638)at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)at android.view.ViewGroup.drawChild(ViewGroup.java:1638) android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)at android.view.View.draw(View.java:6743)at android.widget.FrameLayout.draw(FrameLayout.java:352)atandroid.view。 android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)のViewGroup.drawChild(ViewGroup.java:1640)android。view.View.draw(View.java:6743)at android.widget.FrameLayout.draw(FrameLayout.java:352)at com.android.internal.policy.impl.PhoneWindow $ DecorView.draw(PhoneWindow.java:1847) android.view.ViewRoot.draw(ViewRoot.java:1407)at android.view.ViewRoot.performTraversals(ViewRoot.java:1163)at android.view.ViewRoot.handleMessage(ViewRoot.java:1727)atandroid.os。 Handler.dispatchMessage(Handler.java:99)at android.os.Looper.loop(Looper.java:123)at android.app.ActivityThread.main(ActivityThread.java:4627)at java.lang.reflect.Method.invokeNative (ネイティブメソッド)at java.lang.reflect.Method.invoke(Method.java:521)at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:878)at com.android.internal.os .ZygoteInit.main(ZygoteInit.java:636)at dalvik.system.NativeStart.main(ネイティブメソッド)FrameLayout.draw(FrameLayout.java:352)at com.android.internal.policy.impl.PhoneWindow $ DecorView.draw(PhoneWindow.java:1847)at android.view.ViewRoot.draw(ViewRoot.java:1407)at android .view.ViewRoot.performTraversals(ViewRoot.java:1163)at android.view.ViewRoot.handleMessage(ViewRoot.java:1727)at android.os.Handler.dispatchMessage(Handler.java:99)atandroid.os.Looper。 loop(Looper.java:123)at android.app.ActivityThread.main(ActivityThread.java:4627)at java.lang.reflect.Method.invokeNative(Native Method)at java.lang.reflect.Method.invoke(Method。 java:521)at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:878)at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:636)at dalvik.system.NativeStart .main(ネイティブメソッド)FrameLayout.draw(FrameLayout.java:352)at com.android.internal.policy.impl.PhoneWindow $ DecorView.draw(PhoneWindow.java:1847)at android.view.ViewRoot.draw(ViewRoot.java:1407)at android .view.ViewRoot.performTraversals(ViewRoot.java:1163)at android.view.ViewRoot.handleMessage(ViewRoot.java:1727)at android.os.Handler.dispatchMessage(Handler.java:99)atandroid.os.Looper。 loop(Looper.java:123)at android.app.ActivityThread.main(ActivityThread.java:4627)at java.lang.reflect.Method.invokeNative(Native Method)at java.lang.reflect.Method.invoke(Method。 java:521)at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:878)at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:636)at dalvik.system.NativeStart .main(ネイティブメソッド)draw(PhoneWindow.java:1847)at android.view.ViewRoot.draw(ViewRoot.java:1407)at android.view.ViewRoot.performTraversals(ViewRoot.java:1163)at android.view.ViewRoot.handleMessage(ViewRoot.java :1727)android.os.Handler.dispatchMessage(Handler.java:99)at android.os.Looper.loop(Looper.java:123)at android.app.ActivityThread.main(ActivityThread.java:4627)at java .lang.reflect.Method.invokeNative(Native Method)at java.lang.reflect.Method.invoke(Method.java:521)at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:878) com.android.internal.os.ZygoteInit.main(ZygoteInit.java:636)at dalvik.system.NativeStart.main(ネイティブメソッド)draw(PhoneWindow.java:1847)at android.view.ViewRoot.draw(ViewRoot.java:1407)at android.view.ViewRoot.performTraversals(ViewRoot.java:1163)at android.view.ViewRoot.handleMessage(ViewRoot.java :1727)android.os.Handler.dispatchMessage(Handler.java:99)at android.os.Looper.loop(Looper.java:123)at android.app.ActivityThread.main(ActivityThread.java:4627)at java .lang.reflect.Method.invokeNative(Native Method)at java.lang.reflect.Method.invoke(Method.java:521)at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:878) com.android.internal.os.ZygoteInit.main(ZygoteInit.java:636)at dalvik.system.NativeStart.main(ネイティブメソッド)1727)android.os.Handler.dispatchMessage(Handler.java:99)at android.os.Looper.loop(Looper.java:123)at android.app.ActivityThread.main(ActivityThread.java:4627)atjava。 lang.reflect.Method.invokeNative(Native Method)at java.lang.reflect.Method.invoke(Method.java:521)at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:878)at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:636)at dalvik.system.NativeStart.main(ネイティブメソッド)1727)android.os.Handler.dispatchMessage(Handler.java:99)at android.os.Looper.loop(Looper.java:123)at android.app.ActivityThread.main(ActivityThread.java:4627)atjava。 lang.reflect.Method.invokeNative(Native Method)at java.lang.reflect.Method.invoke(Method.java:521)at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:878)at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:636)at dalvik.system.NativeStart.main(ネイティブメソッド)main(ZygoteInit.java:636)at dalvik.system.NativeStart.main(ネイティブメソッド)main(ZygoteInit.java:636)at dalvik.system.NativeStart.main(ネイティブメソッド)