2012-12-03 25 views
3

我試圖找到一種方式來通知一個依賴組件,當某些行被刪除,所以我可以發出一個選擇查詢,獲取遊標,然後發出刪除或將修改原始光標?是否有更好的方法?這就是我指的是:是由刪除查詢修改的Android選擇查詢遊標嗎?

Cursor c = builder.query(db, projection, selection, selectionArgs, groupBy, having, sortOrder); 
db.delete(table, selection, selectionArgs); 
while (cursor != null && cursor.moveToNext()) { 
    final String name = cursor.getString(0); 
    // send notifications 
} 
c.close(); 

回答

1

如果使用內容提供商來訪問你的數據庫,那麼你可以使用ContentObservers這些正是爲此而設計的:

當您通過內容檢索數據提供您一個URI這樣做,這是該URI,你可以用它來通知ContentObserver的光標已經改變:

getContentResolver().notifyChange (URI, null) 

更多信息,請參見javadocs for notifyChange(...)

我不敢說如果你不使用內容提供者訪問你的數據,你將不得不爲自己編寫自己的解決方案。

+0

我正在使用一個ContentProvider,但是這並沒有給你任何關於除了URI之外被刪除的細節,對嗎?它甚至不會提供發生刪除的信息(只是與URI相對應的數據以某種方式被修改)。 –

+0

你說得對。在這種情況下,您仍然可以使用通知系統,但不刪除行,而是添加可設置爲刪除的狀態列。這樣,您可以在收到通知時查詢具有此標誌的行。 –

+0

@AbdullahJibaly爲什麼你需要這個?(我假設你知道你刪除的每一行)...也許不是刪除你的contentprovider應該標記行刪除(添加列isDeleted)...然後你可以添加另一個URI來處理這些「刪除」的項目,並刪除它們premamently(我使用這種解決方案來同步本地SQLite數據庫與MSSQL)... – Selvin

1

遊標是從數據庫分離的數據結構。即通過任何方式修改數據庫,不會影響已獲取的遊標。

更新

這顯然是錯誤的! ..對不起!

查看評論的詳細信息。感謝@Selvin。

+0

你在哪裏讀過這些內容? CursorWindow(CW)被取出不是整個光標...我認爲,如果fx CW只有10行的大小和整個結果是20,你在第一個CW然後使用刪除然後moveTo(11)將失敗...因爲驅動程序將嘗試要將數據提取到CursorWindow ... – Selvin

+0

要寫入sqlite數據庫的進程,必須獲得'EXCLUSIVE'鎖定。 sqlite只給出一個'EXCLUSIVE'鎖,並且在寫入完成之前沒有其他的鎖。這意味着如果某個進程正在讀取數據庫,那麼sqlite會一直等到這個進程完成讀取,然後給想要寫入的人一個'EXCLUSIVE'鎖。 這除了android'SQLiteDatabase.beginTransaction()'在'EXCLUSIVE'模式下打開一個事務。 http://www.sqlite.org/lockingv3.html http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#beginTransaction%28%29 – kdehairy

+0

也就是說,如果應用程序仍在讀取遊標,則在讀取結束之前,沒有其他人可以寫入數據庫文件。那麼sqlite會給作者一個'EXCLUSIVE'鎖。 抱歉@Selvin爲了便於閱讀,我不得不將評論分成兩部分。 – kdehairy