简体   繁体   English

并发修改异常如何解决?

[英]Concurrent Modification Exception How to Fix It?

Hi I could use some help fixing the Concurrent Modification Exception I'm getting, I think it is something to do with the use of the List and the use of a thread which means I'm attempting to access it at the same time causing it to lock, but I dont know how to fix it, any help? 嗨,我可以使用一些帮助解决我收到的并发修改异常的问题,我认为这与List的使用和线程的使用有关,这意味着我试图同时访问它导致它锁定,但我不知道如何解决,有什么帮助吗?

edit This only occurs after I run the code below twice in a row it works fine only once. 编辑这只会在我连续两次运行下面的代码后发生,并且只能正常工作一次。

Global: List mapOverlays; 全局:列出mapOverlays; PointOverlay pointOverlay; PointOverlay pointOverlay;

In onCreate: 在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);

In getLocs: 在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
}

The problem is likely your call to mapOverlays.add(). 问题可能出在您对mapOverlays.add()的调用。 This is probably happening at the same time another thread or piece of code is iterating over list. 这可能是在另一个线程或代码片段遍历列表的同时发生的。 Concurrent modification exceptions are thrown when one thread is iterating over a collection (typically using an iterator) and another thread tries to structurally change the collection. 当一个线程在集合上进行迭代(通常使用迭代器),而另一个线程尝试从结构上更改集合时,将引发并发修改异常。

I would suggest looking for places where mapOverlays may be accessed simultaneously from two different threads and synchrnoizing on the list. 我建议寻找可以从两个不同的线程同时访问mapOverlays并在列表上进行同步的地方。

The problem is that you are modifying the list of overlay items while some other thread is reading the list. 问题是您正在修改覆盖项列表,而其他一些线程正在读取该列表。

I suspect the problem has to do with the way you are doing your background tasks. 我怀疑问题与您执行后台任务的方式有关。 You can only modify the UI on the UI (main thread). 您只能在UI(主线程)上修改UI。 You shouldn't be adding the overlay items to the Map in the Thread. 您不应该在Thread中将叠加项添加到Map中。 Check out AsyncTask to see how to properly do background tasks and also update the UI. 请查看AsyncTask,以了解如何正确执行后台任务以及更新UI。 It would also help to read the article on Threading on the Android dev site. 在Android开发人员网站上阅读有关线程化的文章也将有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM