Android MapView ConcurrentModificationException

Android MapView ConcurrentModificationException,android,exception,concurrency,android-mapview,Android,Exception,Concurrency,Android Mapview,正如标题所示,在尝试在两个位置之间创建路由时,我(有时)会遇到concurrentmodificationexception。。。 这是我的代码(如果你想知道MyOverlay没有尝试访问地图中的其他覆盖) 私有类fillRouteTask扩展异步任务{ /** *创建要调用以获取路由的url * *@param src *@param dest *@返回 */ 专用StringBuilder createUrl(地质点src、地质点dest){ //连接到地图web服务 StringBuil

正如标题所示,在尝试在两个位置之间创建路由时,我(有时)会遇到concurrentmodificationexception。。。 这是我的代码(如果你想知道MyOverlay没有尝试访问地图中的其他覆盖)

私有类fillRouteTask扩展异步任务{
/**
*创建要调用以获取路由的url
* 
*@param src
*@param dest
*@返回
*/
专用StringBuilder createUrl(地质点src、地质点dest){
//连接到地图web服务
StringBuilder urlString=新的StringBuilder();
urlString.append(“http://maps.google.com/maps?f=d&hl=en");
urlString.append(“&saddr=”);//来自
追加(双精度)
.toString((双)src.getLatitudeE6()/1.0E6));
urlString.append(“,”);
追加(双精度)
.toString((双)src.getLongitudeE6()/1.0E6));
urlString.append(“&daddr=”);//到
追加(双精度)
.toString((双)dest.getLatitudeE6()/1.0E6));
urlString.append(“,”);
追加(双精度)
.toString((双)dest.getLongitudeE6()/1.0E6));
追加(“&ie=UTF8&0&om=0&output=kml”);
Log.d(“xxx”,“URL=“+urlString.toString());
返回URL字符串;
}
/**
*创建到google url的连接
* 
*@param src
*@param dest
*@返回
*/
专用字符串连接器(地质点src、地质点dest){
//获取kml(XML)文档,并对其进行解析以获取
//坐标(方向)
//路线)。
单据单据=空;
HttpURLConnection-urlConnection=null;
URL=null;
试一试{
url=新url(createUrl(src,dest.toString());
urlConnection=(HttpURLConnection)url.openConnection();
urlConnection.setRequestMethod(“GET”);
urlConnection.setDoOutput(true);
urlConnection.setDoInput(true);
urlConnection.connect();
DocumentBuilderFactory dbf=DocumentBuilderFactory
.newInstance();
DocumentBuilder db=dbf.newDocumentBuilder();
doc=db.parse(urlConnection.getInputStream());
如果(doc.getElementsByTagName(“GeometryCollection”)!=null
&&getElementsByTagName文件(“GeometryCollection”)
.getLength()>0){
返回doc.getElementsByTagName(“GeometryCollection”).item(
0.getFirstChild().getFirstChild().getFirstChild()
.getNodeValue();
}
}捕获(格式错误){
Log.d(“test”,例如getLocalizedMessage());
}捕获(IOE异常){
Log.d(“test”,例如getLocalizedMessage());
}捕获(ParserConfiguration异常e){
Log.d(“test”,例如getLocalizedMessage());
}捕获(SAXE异常){
Log.d(“test”,例如getLocalizedMessage());
}
返回null;
}
受保护的Void doInBackground(Void…arg0){
试一试{
//获取地图中当前的覆盖图
列表覆盖=集合。同步列表(mapView
.getOverlays());
字符串路径=connectToUrl(源、目标);
if(路径!=null){
Log.d(“xxx”,“path=“+path”);
String[]pairs=path.split(“”);
字符串[]lngLat=pairs[0]。拆分(“,”;
地质点startGP=新的地质点((int)(双精度)
.parseDouble(lngLat[1])*1E6,(int)(双精度)
.parseDouble(lngLat[0])*1E6);
添加(新的MyOverlay(startGP,startGP,1));
地质点gp1;
地质点gp2=startGP;
对于(int i=1;i
您只能修改UI线程上的覆盖。您需要在AsyncTask的onPostExecute方法中将新数据添加到覆盖中。

您只能在UI线程上修改覆盖。您需要在AsyncTask的onPostExecute方法中将新数据添加到覆盖中。

是否可以将异常stacktrace添加到问题?是否可以将异常stacktrace添加到问题?
    private class fillRouteTask extends AsyncTask<Void, GeoPoint, Void> {

  /**
   * create the url to call to get the route
   * 
   * @param src
   * @param dest
   * @return
   */
  private StringBuilder createUrl(GeoPoint src, GeoPoint dest) {
   // connect to map web service
   StringBuilder urlString = new StringBuilder();
   urlString.append("http://maps.google.com/maps?f=d&hl=en");
   urlString.append("&saddr=");// from
   urlString.append(Double
     .toString((double) src.getLatitudeE6() / 1.0E6));
   urlString.append(",");
   urlString.append(Double
     .toString((double) src.getLongitudeE6() / 1.0E6));
   urlString.append("&daddr=");// to
   urlString.append(Double
     .toString((double) dest.getLatitudeE6() / 1.0E6));
   urlString.append(",");
   urlString.append(Double
     .toString((double) dest.getLongitudeE6() / 1.0E6));
   urlString.append("&ie=UTF8&0&om=0&output=kml");
   Log.d("xxx", "URL=" + urlString.toString());

   return urlString;
  }

  /**
   * create the connection to google url
   * 
   * @param src
   * @param dest
   * @return
   */
  private String connectToUrl(GeoPoint src, GeoPoint dest) {

   // get the kml (XML) doc. And parse it to get the
   // coordinates(direction
   // route).
   Document doc = null;
   HttpURLConnection urlConnection = null;
   URL url = null;
   try {
    url = new URL(createUrl(src, dest).toString());
    urlConnection = (HttpURLConnection) url.openConnection();
    urlConnection.setRequestMethod("GET");
    urlConnection.setDoOutput(true);
    urlConnection.setDoInput(true);
    urlConnection.connect();

    DocumentBuilderFactory dbf = DocumentBuilderFactory
      .newInstance();
    DocumentBuilder db = dbf.newDocumentBuilder();
    doc = db.parse(urlConnection.getInputStream());

    if (doc.getElementsByTagName("GeometryCollection") != null
      && doc.getElementsByTagName("GeometryCollection")
        .getLength() > 0) {
     return doc.getElementsByTagName("GeometryCollection").item(
       0).getFirstChild().getFirstChild().getFirstChild()
       .getNodeValue();
    }

   } catch (MalformedURLException e) {
    Log.d("test", e.getLocalizedMessage());
   } catch (IOException e) {
    Log.d("test", e.getLocalizedMessage());
   } catch (ParserConfigurationException e) {
    Log.d("test", e.getLocalizedMessage());
   } catch (SAXException e) {
    Log.d("test", e.getLocalizedMessage());
   }
   return null;
  }

  protected Void doInBackground(Void... arg0) {
   try {
    // get the current overlays present in the map
    List<Overlay> overs = Collections.synchronizedList(mapView
      .getOverlays());
    String path = connectToUrl(orig, dest);
    if (path != null) {
     Log.d("xxx", "path=" + path);
     String[] pairs = path.split(" ");
     String[] lngLat = pairs[0].split(",");

     GeoPoint startGP = new GeoPoint((int) (Double
       .parseDouble(lngLat[1]) * 1E6), (int) (Double
       .parseDouble(lngLat[0]) * 1E6));

     overs.add(new MyOverlay(startGP, startGP, 1));
     GeoPoint gp1;
     GeoPoint gp2 = startGP;
     for (int i = 1; i < pairs.length; i++) // the last one would
     // be
     // crash
     {
      lngLat = pairs[i].split(",");
      gp1 = gp2;
      // watch out! For GeoPoint, first:latitude,
      // second:longitude
      gp2 = new GeoPoint(
        (int) (Double.parseDouble(lngLat[1]) * 1E6),
        (int) (Double.parseDouble(lngLat[0]) * 1E6));
      Log.d("xxx", "pair:" + pairs[i]);
      publishProgress(gp1, gp2);
     }
     overs.add(new MyOverlay(dest, dest, 3)); // use
     // the
     // default
     // color
     drawn = false;
    } else {
     m_handler.post(new Runnable() {

      public void run() {
       Toast.makeText(getApplicationContext(),
         "Problem in getting the directions",
         Toast.LENGTH_SHORT).show();
      }
     });
    }
   } catch (Exception e) {
    m_handler.post(new Runnable() {

     public void run() {
      Toast.makeText(getApplicationContext(),
        R.string.errorrouteLoad, Toast.LENGTH_LONG)
        .show();
     }
    });
   }
   return null;

  }

  /*
   * (non-Javadoc)
   * 
   * @see android.os.AsyncTask#onProgressUpdate(Progress[])
   */
  @Override
  protected void onProgressUpdate(GeoPoint... values) {
   // TODO Auto-generated method stub
   List<Overlay> overs = Collections.synchronizedList(mapView
     .getOverlays());
   overs.add(new MyOverlay(values[0], values[1], 2, 0x0000ff));

  }

  /*
   * (non-Javadoc)
   * 
   * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
   */
  @Override
  protected void onPostExecute(Void result) {
   // TODO Auto-generated method stub
   Log.d("routing", "done");
   mapView.postInvalidate();
  }
 }