2011-08-25 60 views
2

在Android中重新使用遊標對象以在數據庫上進行多個查詢是否是一種很好的做法?我需要在查詢之間調用deactivate()嗎?我在第二個查詢後停用遊標,但我仍然在logcat中收到DatabaseObjectNotClosedException警告。Android重新使用遊標

+1

遊標不會進行查詢,它保存查詢的結果。我看不出有什麼理由不能將它設置爲空,然後重新使用它。 – Jack

+0

經過再看看文檔,我相信我需要調用deactivate()然後請求一個新的遊標。我不相信在請求新的遊標之前將它設置爲null是必要的。 – zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz

回答

0

以我的經驗,你可以將光標設置爲新的東西。我嘗試過在其上調用deactivate(),但是這弄亂了我的應用程序,所以我決定不使用它。我不知道這是否是好的做法,但它對我來說工作得很好,就我的測試而言,它似乎不會泄漏或放慢速度。

0

那麼,requery()已被棄用,bur由於某種原因deactivate()不是。如果沒有另一個,你不能真正使用它,所以我猜你可能會認爲你不應該使用deactivate()。在任何情況下,一旦完成它就關閉一個光標將消除所有那些討厭的DatabaseObjectNotClosedException的。新的加載器框架鼓勵返回新的遊標,舊代碼在您替換它們時會自動關閉。

+0

這是不正確的。您可以使用停用而不使用重新查詢。 Requery已被棄用,因爲您不需要調用它。你可以調用deactivate,然後通過調用database.rawQuery()或類似的東西來創建一個新的遊標。 – zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz

+0

爲什麼叫停用呢? –

1

requery()deactivate()現在已被棄用(自API 11開始的第一個,後者自API 16開始)。我正在回答這個差不多7年的問題,因爲我相信還沒有給出正確的答案。

根據我的經驗,重新使用Cursor對象是一種不好的做法。我的SQLiteOpenHelper類的實現有幾種方法,我關閉了所有這些對象中的Cursor對象 - 並且我相信由於在每個方法結束時關閉了Cursor對象,所以它是正確的。但在某些方法中,我重新使用一個Cursor對象來保存來自多個查詢的結果(首先我運行了一個查詢,然後我讀取並使用了Cursor的結果,然後運行了一個我認爲會簡單的查詢覆蓋已使用的Cursor中的舊結果)。啓用StrictMode證明了我的錯誤。我開始變得DatabaseObjectNotClosedException崩潰。

我修復它不再使用Cursor對象。現在我爲每個查詢創建一個新的Cursor變量,然後讀取並保存結果,並且我在Cursor上調用close()方法,不再使用它。如果我需要在該方法中運行另一個查詢,我故意不再使用舊的Cursor,而且我總是創建一個新變量。即使啓用了StrictMode,我也不會再收到任何警告或崩潰。我相信垃圾收集器的工作是正確的,所以我不認爲創建Cursor類的多個實例是一個巨大的問題。另一方面,僅使用一個Cursor對象就像一個問題似乎 - 因此您的警告和我的崩潰StrictMode

我不是數據庫專家,我仍然在學習Android編程的最佳實踐,但我相信在這個話題上我是正確的 - 不要重複使用Cursor對象,或者您可以開始獲取內存泄漏,警告甚至崩潰。