Прежде всего, я не знаю, где, я не знаю, почему, я получаю ConcurrentModificationException. Мой Logcat не работает (или просто я не могу его использовать), но никогда не показывает никакой информации об исключениях (я прочитал много статей об этом, и ничего не помогло, может быть, не удалось правильно отладить мой телефон)Android API 7 (2.1), MapView, MultiThreading, ConcurrentModificationException
Во-вторых Сожалеем о моем замешательстве английском, я попытаюсь сформулировать так ясно, как я могу, коды могли бы помочь, пожалуйста, помогите мне
Таким образом, проблема является следующим:
я использую MAPview и 5 пользовательских CustomItemizedOverlay (Источник № 1). Из MapView я запускаю некоторые (1, 2, max 5) потоки в webservice (Источник 2), и после того, как я получаю результаты назад (это список), я рисую их в mapoverlay (источник 3)
так MapView (реализует 5 ResponseHandlerInterfaces) отправляет запросы в webservice через myActions (extends Thread), и когда действия получают ответы, они вызывают методы responseHandler.reportResponseList (List List). (MapView вернуть контроль прямо здесь)
and all of it causes ConcurrentModificationException sometimes
(rarely ArrayIndexOutOfBoundsException)
я получил опцию Активность установить необходимые списки и я также получил кнопку Обновить, чтобы получить списки. позвольте мне привести вас к одному примеру.
Я только что открыл MapView, он пуст. Мне нужен только один вид объектов. Я подключаюсь к обновлению, после сетевой связи, я получаю маркеры на моем карте. круто, он работает. Теперь я перейду в «Параметры», и я задаю больше объектов для запроса. Используйте Refresh снова в mapview, и иногда я получаю все виды объектов, иногда я получаю ConcurrentModificationException.
Источник No. 1
public class CustomItemizedOverlay<T> extends ItemizedOverlay<T>{
private Context mContext;
private Object lock = new Object();
private CopyOnWriteArrayList<T> overlays = new CopyOnWriteArrayList<T>();
public CustomItemizedOverlay(Drawable marker, Context context) {
super(boundCenterBottom(marker));
this.mContext = context;
populate();
}
@Override
protected boolean onTap(int index){
// doesn't matter
}
public void clear(){
synchronized (lock) {
overlays.clear();
}
}
public void addOverlay(T overlay){
synchronized (lock) {
overlays.add(overlay);
setLastFocusedIndex(-1);
populate();
}
}
public void removeOverlay(int selected){
synchronized (lock) {
overlays.remove(selected);
populate();
setLastFocusedIndex(-1);
}
}
@Override
protected T createItem(int i) {
synchronized (lock) {
return overlays.get(i);
}
}
@Override
public int size() {
synchronized (lock) {
return overlays.size();
}
}
public void setLock(Object o){
this.lock = o;
}
}
Источник No. 2
MapView:
public class MyMap extends MapActivity implements LocationListener, RestResPonseHandler { // there are 5 type of responsehandlers, one for each overlay
private MapView mapView;
private MyLocationOverlay myLocationOverlay;
private Object lock = new Object();
private CustomItemizedOverlay<CustomOverlayItem<MyObject1>> my1Overlay;
private CustomItemizedOverlay<CustomOverlayItem<MyObject2>> my2Overlay;
private CustomItemizedOverlay<CustomOverlayItem<MyObject3>> my3Overlay;
private CustomItemizedOverlay<CustomOverlayItem<MyObject4>> my4Overlay;
private CustomItemizedOverlay<CustomOverlayItem<MyObject5>> my5Overlay;
public void getObject1List(){ // there are 5 getList methods
new RestAction(this).start(); // 'this' is the object which implements required RestResponseHandler interface. in every case it will be 'this'. MyMap implements all kind of required RestResponseHandler interfaces
}
Источник № 3 (не основной поток) // Это шаблон для каждого 'CustomItemizedOverlay метод заполнения'. После того, как действия отчетов результатов (список объектов), MapView заполняет фактическую накладку с OverlayItems
@Override
public void reportResponseList(List<MyObject1> objects) {
if (my1Overlay == null){
List<Overlay> mapOverlays = mapView.getOverlays();
Drawable marker = this.getResources().getDrawable(R.drawable.icon);
my1Overlay = new CustomItemizedOverlay<CustomOverlayItem<MyObject1>>(marker, this);
my1Overlay.setLock(lock); // MyMap has lock object, look at source 2 (also CustomItemizedOverlay (source 1))
mapOverlays.add(my1Overlay);
} else {
my1Overlay.clear();
}
synchronized (lock) {
for(int i=0;i<objects.size();++i){
MyObject1 object = objects.get(i);
CustomOverlayItem<MyObject1> item = new CustomOverlayItem<CustomBuilding>(object.getPositionId(), object);
my1Overlay.addOverlay(item);
}
refreshView();
}
}
Где сообщениями refreshView запускаемым в главный поток, чтобы обновить MAPview.
public void refreshView(){
new Thread(new Runnable(){
@Override
public void run(){
mapView.post(new Runnable(){
@Override
public void run(){
mapView.invalidate();
}
});
}
}).start();
}
Решение: После ответа CommonsWare, я изменил мой источник:
@Override
public void reportResponseList(final List<MyObject1> objects) {
if (my1Overlay == null){
List<Overlay> mapOverlays = mapView.getOverlays();
Drawable marker = this.getResources().getDrawable(R.drawable.icon);
my1Overlay = new CustomItemizedOverlay<CustomOverlayItem<MyObject1>>(marker, this);
my1Overlay.setLock(lock);
mapOverlays.add(my1Overlay);
} else {
runOnUiThread(new Runnable(){
@Override
public void run(){
my1Overlay.clear();
}
});
}
runOnUiThread(new Runnable(){
@Override
public void run(){
for(int i=0;i<objects.size();++i){
MyObject1 object = objects.get(i);
CustomOverlayItem<MyObject1> item = new CustomOverlayItem<MyObject1>(object.getPositionId(), object);
my1Overlay.addOverlay(item);
}
refreshView();
}
});
}
и теперь в этот момент, кажется, работает. я не знаю, насколько это красиво, но, похоже, работает. (возможно, метод mapOverlays.add() должен быть включен в основной поток тоже) Большое спасибо.
Должен ли my1Overlay.clear() и синхронизированный цикл работать в основном потоке? – Victor
@Victor: Это еще одна возможность, хотя вам больше не нужно, чтобы она была «синхронизирована», если все, кто обращается к ней, делают это в главном потоке приложения. – CommonsWare
и smogло mapOverlays.add (my1Overlay); быть на основной теме? – Victor