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

Android SQLite CursorWindow 併發讀寫異常:游標失效與資料複製策略

     編輯:程式設計綜合問答

異常場景

  • UI 執行緒持有 Cursor 綁定 ListView(透過 CursorAdapter)。
  • 背景執行緒刪除資料表尾部資料,發送 Handler 通知 UI 換新 Cursor + notifyDataSetChanged()。
  • 在通知送達前,使用者滑動列表觸發 getView() → cursor.moveToPosition(190),但舊 CursorWindow 僅剩 180 列 → CursorWindowAllocationException。

根因

Cursor 及其底層 CursorWindow 是**資料快照**,不會自動同步資料庫變更。刪除資料後舊 Cursor 仍指向舊快照,位置索引失效。

解決策略

  1. 資料複製到記憶體集合(推薦):
    查詢時將所有列讀入 List> 或自定 Bean List,Cursor 用完即關閉。
    Adapter 綁定 List,背景執行緒刪除資料庫後,同步更新 List(移除項目)再 notifyDataSetChanged(),**完全繞過 Cursor 併發問題**。
  2. 重查換 Cursor:
    背景執行緒刪除後,立即在背景執行緒 requery() 或重新 query() 取得新 Cursor,透過 Handler 傳給 UI 執行緒 swapCursor(newCursor)。
    需確保 UI 執行緒在收到新 Cursor 前**不再存取舊 Cursor**(可加鎖或標記旗標)。
  3. ContentProvider + LoaderManager:
    使用 CursorLoader 自動監測資料變更(需 ContentResolver.notifyChange(uri)),框架層處理 Cursor 更換,最標準但引入較重架構。

核心原則

**不要在跨執行緒共享 Cursor 且同時修改資料庫**。資料複製到不變集合是最輕量穩健的方案。

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