1

ハッシュマップを反復処理し、反復中にキーを使用しようとしています。反復が UI スレッドをブロックしていたため、非同期タスク内で使用することにしました。

私のハッシュマップにはキーとして LatLng があり、オブジェクトとしてマーカーがあります。反復中にキーを取得し、正常に動作する新しい LatLng に渡すと、この新しい LatLng を使用しようとするとjava.util.ConcurrentModificationException例外が発生します。奇妙なことに、AsyncTask なしでコードを使用すると、これは起こりません。

これが私のコードです

    class AddCityMarker extends AsyncTask<Integer, Integer, String> {

    protected String doInBackground(Integer... counter) {           

        //CityMarker cMarker;
        LatLng marker_loc;

        List<String> city_markers = new ArrayList<String>();
        if(displayed.size() > 0){

            Iterator<HashMap.Entry<LatLng, Marker>> myIterator = displayed.entrySet().iterator();
            while(myIterator.hasNext()) {
                //cMarker = new CityMarker();
                HashMap.Entry<LatLng, Marker> entry = myIterator.next();                    
                marker_loc = entry.getKey();

                Log.i("ZOOM", "Key = " + marker_loc + ", Value = " + entry.getValue());

                List<Address> addresses = null;                     
                try {
                  //This is where I get the error
                    addresses = gcode.getFromLocation(marker_loc.latitude, marker_loc.longitude, 1);
                } catch (IOException e) {
                    e.printStackTrace();
                }

                if(addresses.size() > 0) {  
                    if(!city_markers.contains(addresses.get(0).getLocality())){
                        city_markers.add(addresses.get(0).getLocality());
                        //map.addMarker(new MarkerOptions().position(marker_loc).snippet("CITY"));
                    }                           
                }
            }                   
        }


        return null;
    }

    protected void onPostExecute(String jsonResult) {

        try {   

            if(isClubMarkers){
                map.clear();
                isClubMarkers = false;
            }
            displayed.clear();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
4

1 に答える 1

1

Android 1.6 から Android HoneyComb まで、非同期タスクは並列モードで実行されています。つまり、別のスレッドのようです。あなたのケースでは、非同期タスクを複数回呼び出している可能性があり、反復のために同じ HashMap にアクセスしようとする場合があります。HashMap の代わりに「ConcurrentHashMap」を使用すると、この例外を回避できます。ただし、適切な方法は、非同期タスクが複数回呼び出されているかどうかを特定し、存在する場合は回避することです。これは、非同期タスクが同じことを繰り返しているときに Hashmap を操作しようとした場合にも発生する可能性があります。その場合は、スレッドセーフな「ConcurrentHashMap」を使用してください。

于 2013-08-12T11:24:13.833 に答える