首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android FilterAdapter 異常閃現「北京市」問題分析

     編輯:程式設計綜合問答

現象

輸入無效搜索內容(如 `3/5/9#!¥`),列表閃現「北京市」後恢復正常,且非必現。

代碼疑點

  1. Filter 執行線程:`performFiltering` 運行在後台線程,`publishResults` 在 UI 線程。若 `filter()` 多次快速調用,舊結果可能在新結果後到達,導致 UI 閃現舊數據。
  2. 原始數據列表 `list` 被直接修改:`publishResults` 中 `list = (List) results.values;` 替換了引用,但 `getView` 可能仍持有舊列表引用,造成數據不一致。
  3. 拼音列表 `spylist` 未同步過濾:過濾邏輯中使用 `spylist.get(i)`,但 `spylist` 未隨 `list` 同步變化,導致索引錯位,匹配到錯誤項(如索引 0 的「北京市」)。
  4. 異步任務未取消:未在新過濾前取消舊任務,導致結果競態。

修復建議

  1. 在 `performFiltering` 開頭檢查 `Thread.interrupted()`,或用 `Filter` 子類覆寫 `cancel()` 取消舊任務。
  2. 過濾時同時構建新的 `newList` 和 `newSpyList`,保持索引一一對應,`publishResults` 時成對替換。
  3. 使用 `ArrayList` 而非 `List` 確保隨機訪問性能,避免 `remove` 導致 O(n²)。
  4. 調試時在 `performFiltering`/`publishResults` 打印線程 ID、列表大小、首項內容,定位競態時機。

優化方向

考慮用 `RecyclerView` + `ListAdapter` + `DiffUtil` 替代 `ListView` + `Filterable`,獲得更穩定的異步列表更新體驗。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved