2016-12-24 4 views
1

Einige Quelle-Code, den ich geerbt haben, wirft manchmal eine ConcurrentModificationException auf dieser Linie:ConcurrentModificationException innen PublishResult - ArrayAdapter

for (String c : filteredList) { 

Körper:

@Override 
protected void publishResults(CharSequence constraint, FilterResults results) { 
    ArrayList<String> filteredList = (ArrayList<String>) results.values; 
    if (results != null && results.count > 0) { 
     clear(); 
     for (String c : filteredList) { 
      add(c); 
     } 
     notifyDataSetChanged(); 
    } 
} 

Wie soll ich diesen Fehler verhindern?

+1

Normalerweise verwende ich nur die gefilterte Liste, sondern direkt eine weitere Runde der Iteration. Sie können immer einen Verweis auf die vollständige Liste halten, wenn das Filterkriterium null/leer ist. – Karakuri

+1

das ist freilich viel schwieriger mit 'ArrayAdapter' zu tun, weil viel von seinem Umgang mit den Elementen internen und nicht zur Verfügung (und die API leider nicht über eine' setItems (List ) 'Methode, die wirklich bedauerlich ist) . Ich glaube, Sie können Ihr Leben einfacher durch die Erweiterung BaseAdapter stattdessen machen - die Dinge ArrayAdapter ziemlich trivial liefern, sind neu. – Karakuri

+0

Was wäre ein Hot-Fix zu diesem fatalen Problem oben, während ArrayAdapter w/o Verlängerung BaseAdapter mit? –

Antwort

2

ConcurrentModificationException:

Es ist im allgemeinen nicht zulässig, ein Thread eine Sammlung zu ändern, während ein anderer Thread über sie iterieren ist ...

Ein Hotfix-Lösung, die das Klonen würde ArrayList<String>, bevor es iterieren:

ArrayList<String> filteredList = (ArrayList<String>) results.values.clone(); 

Sie Beachten Sie, dass Sie in diesem Zeitraum doppelt so viel RAM verbrauchen, wenn die Liste groß ist.

btw, ich würde zuerst die Validierungen ausgeführt werden, bevor Karte/klonen Sie Ihre Liste, die ersten 2 Zeilen Schalten, als Performance-Verbesserung:

@Override 
protected void publishResults(CharSequence constraint, FilterResults results) { 
    if (results != null && results.count > 0) { 
     ArrayList<String> filteredList = (ArrayList<String>) results.values.clone(); 
     clear(); 
     for (String c : filteredList) { 
      add(c); 
     } 
     notifyDataSetChanged(); 
    } 
} 

Hoffe, es hilft! Cheers,

Verwandte Themen