2016-12-24 19 views
1

我有時繼承了一些源代碼拋出該線路上一個ConcurrentModificationException的:ConcurrentModificationException的內部PublishResult - ArrayAdapter

for (String c : filteredList) { 

體:

@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(); 
    } 
} 

我應該如何避免這種錯誤的發生?

+1

通常我只是直接使用過濾列表,而不是進一步的迭代。您可以隨時保留對過濾條件爲空/空時的完整列表的引用。 – Karakuri

+1

無可否認,使用'ArrayAdapter'很難做到這一點,因爲它對項目的大部分處理都是內部的,並且對您不可用(並且API可惜沒有'setItems(列表)'方法,這確實是不幸的) 。我認爲你可以通過擴展BaseAdapter來簡化你的生活 - ArrayAdapter提供的東西很容易重新創建。 – Karakuri

+0

使用ArrayAdapter而不使用擴展BaseAdapter時,上述致命問題的熱修復會是什麼? –

回答

2

ConcurrentModificationException的:

這不是一般允許一個線程修改集合,而另一個線程上進行迭代...

修補程序的解決方案,將被克隆ArrayList<String>,重複之前:

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

你需要考慮的是,如果列表很大,那麼在這段時間內你將消耗兩倍的RAM。

順便說一句,我會首先運行驗證,地圖前/克隆你的列表中,您切換頭兩行,作爲性能改進:

@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(); 
    } 
} 

希望它能幫助!乾杯,

相關問題