并发修改异常如何解决?

时间:2011-03-12 02:00:31

标签: java android exception

您好我可以使用一些帮助修复我正在获得的并发修改异常,我认为这与使用List和使用线程有关,这意味着我试图在同一时间访问它时间导致它锁定,但我不知道如何解决它,任何帮助?

编辑这只发生在我连续两次运行下面的代码后才能正常运行一次。

全局:     列表mapOverlays;     PointOverlay pointOverlay;

在onCreate中:

//Get the current overlays of the mapView and store them in the list
mapOverlays = mapView.getOverlays();
//Get the image to be used as a marker
drawable = this.getResources().getDrawable(R.drawable.guy);
//Create the drawable and bind its centre to the bottom centre
pointOverlay = new PointOverlay(drawable, this);

在getLocs中:

//Used to grab location near to the phones current location and then draw
//the location within range to the map
public void getNearLocs(View v)
{
    new Thread()//create new thread
    {
    public void run()//start thread
    {
        //Grab new location
        loc = locManager.getLastKnownLocation(locManager.getBestProvider(locCriteria, true));

        //Get the lat and long
        double lat = loc.getLatitude();
        double lon = loc.getLongitude();

        //Convert these to string to prepare for sending to server
        String sLat = Double.toString(lat);
        String sLon = Double.toString(lon);

        //Add them to a name value pair
        latLonPair.add(new BasicNameValuePair("lat", sLat));
        latLonPair.add(new BasicNameValuePair("lon", sLon));
        Log.i("getNearLocs", "Lon: " + sLon + " Lat: " + sLat);//debug

        //http post
        try
        {
            //Create a new httpClient
            HttpClient httpclient = new DefaultHttpClient();
            //Create a post URL
            HttpPost httppost = new HttpPost("http://www.nhunston.com/ProjectHeat/getLocs.php");
            //set the Entity of the post (information to be sent) as a new encoded URL of which the info is the nameValuePairs         
            httppost.setEntity(new UrlEncodedFormEntity(latLonPair));
            //Execute the post using the post created earlier and assign this to a response
            HttpResponse response = httpclient.execute(httppost);//send data

            //Get the response from the PHP (server)
            InputStream in = response.getEntity().getContent();

            //Read in the data and store it in a JSONArray
            JSONArray jPointsArray = new JSONArray(convertStreamToString(in)); 

            Log.i("From Server:", jPointsArray.toString()); //log the result 

            //Clear the mapView ready for redrawing
            mapView.postInvalidate();

            //Loop through the JSONArray
            for(int i = 0; i < jPointsArray.length(); i++)
            {
                //Get the object stored at the JSONArray position i
                JSONObject jPointsObj = jPointsArray.getJSONObject(i);

                //Extract the values out of the objects by using their names
                //Cast to int 
                //Then* 1e6 to convert to micro-degrees
                GeoPoint point = new GeoPoint((int)(jPointsObj.getDouble("lat") *1e6), 
                                              (int)(jPointsObj.getDouble("lon") *1e6)); 
                //Log for debugging
                Log.i("From Server:", String.valueOf((int) (jPointsObj.getDouble("lat") * 1e6))); //log the result
                Log.i("From Server:", String.valueOf((int) (jPointsObj.getDouble("lon") * 1e6))); //log the result

                //Create a new overlayItem at the above geoPosition (text optional)
                OverlayItem overlayitem = new OverlayItem(point, "Test", "Test");

                //Add the item to the overlay
                pointOverlay.addOverlay(overlayitem);
                //Add the overlay to the mapView
                mapOverlays.add(pointOverlay);
                //mapView.refreshDrawableState();
            }   
        }
        catch(Exception e)
        {
            Log.e("getNearLocs", e.toString());
        }
    }
}.start();//start thread
}

2 个答案:

答案 0 :(得分:4)

问题是可能您对mapOverlays.add()的调用。这可能是在另一个线程或代码片段迭代列表的同时发生的。当一个线程在一个集合上迭代(通常使用迭代器)而另一个线程试图从结构上改变集合时,抛出并发修改异常。

我建议寻找可以从两个不同的线程同时访问mapOverlays并在列表上同步的地方。

答案 1 :(得分:4)

问题是您正在修改覆盖项列表,而其他一些线程正在读取列表。

我怀疑问题与您执行后台任务的方式有关。您只能修改UI(主线程)上的UI。您不应该将重叠项添加到线程中的Map。查看AsyncTask,了解如何正确执行后台任务以及更新用户界面。阅读Android开发网站上的Threading文章也很有帮助。