Исключение одновременной модификации Как это исправить? - PullRequest
1 голос
/ 12 марта 2011

Привет, я мог бы помочь с исправлением полученного исключения Concurrent Modification. Я думаю, что это связано с использованием List и использованием потока, что означает, что я пытаюсь получить к нему доступ одновременно время, чтобы заставить его заблокировать, но я не знаю, как это исправить, любая помощь?

edit Это происходит только после того, как я запускаю приведенный ниже код дважды подряд, он работает нормально только один раз.

Global: Список mapOverlays; PointOverlay pointOverlay;

InCreate:

//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 ]

4 голосов
/ 12 марта 2011

Проблема в том, что вы изменяете список наложенных элементов, пока какой-то другой поток читает этот список.

Я подозреваю, что проблема связана с тем, как вы выполняете свои фоновые задачи.Вы можете изменять только пользовательский интерфейс (основной поток).Вы не должны добавлять элементы наложения на карту в теме.Проверьте AsyncTask , чтобы увидеть, как правильно выполнять фоновые задачи, а также обновить пользовательский интерфейс.Также было бы полезно прочитать статью о Threading на сайте разработчика Android.

4 голосов
/ 12 марта 2011

Проблема в вероятности вашего вызова mapOverlays.add ().Это, вероятно, происходит в то же время, когда другой поток или фрагмент кода перебирает список.Одновременные исключения модификации генерируются, когда один поток выполняет итерацию по коллекции (как правило, с использованием итератора), а другой поток пытается структурно изменить коллекцию.

Я бы предложил поискать места, где mapOverlays можно получить одновременно из двух разныхтемы и синхронизация в списке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...