2013-05-28 65 views
0

我有碎片,在那裏我緩存在每一個片段的數據。我在從服務器doInBackground方法下載其緩存數據在的AsyncTask,它在onPostExecute保存到我的數據庫。所以我總是在onPostExecution中打開數據庫連接。如果我滾動「快速」扔碎片,我認爲AsyncTasks通過預覽實例,將有一排android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:224)在那裏我打開連接(獲得dbHelper.getWritableDatabase()的Android的AsyncTask鎖定數據庫

我認爲有兩種方法來解決這樣的:

  • 的onPostExecution方法要等到預覽的AsyncTask(onPostExecution)是完成

  • 有使用的的AsyncTask的所有實例相同的數據庫連接的方式,沒有鎖定他們的海誓山盟

這是正確的嗎?有人有一個想法,該怎麼做?

回答

1

我認爲你正在尋找能在這個帖子中找到的信息:

What are the best practices for SQLite on Android?

至於你使用onPostExecution的保存在數據庫中的數據,因爲SQLiteDatabase類是線程安全,如果您在doInBackground方法中執行應用程序,您的應用程序將會更快(並且仍然安全)。

請記住,如果保存數據是由多個SQL查詢,很容易以確保它們通過使用交易自動執行(沒有其他線程的干擾):

SQLiteDatabase's beginTransaction() at the Android developers website

這順便說一句應該還是使用(在一個單一的交易將1000線速度的東西相當向上)

希望這有助於

+0

感謝您的幫助! 不知道爲什麼,但我曾經以爲只能訪問主線程中的文件系統,其中onPostExecute,而不是doInBackground正在運行。我很驚訝地看到,它也在這裏工作!我現在用事務包圍了我所有的sql查詢。永遠不要關閉遊標(這是通過引用的帖子中的鏈接推薦的,[單個SQLite連接](http://touchlabblog.tumblr.com/post/24474750219/single-sqlite-connection))解決了鎖定問題一方面,但另一方面它似乎是一個骯髒的伎倆。或者我錯了? – lis

+0

「永不關閉遊標」是什麼意思? AFAIK遊標必須關閉,否則Android會投訴(通常非常大聲,尤其是2.2),甚至會引發異常。你可能是指「從不關閉SQLiteDatabase」?如果是這樣,那就沒問題了:在我的應用程序中,我使用保存在應用程序中的數據庫單例,它工作正常(事實上,在多個數據庫實例出現一些不好的體驗後,我轉向了這種方法)。希望它有幫助 – Rick77

5

我會建議你使用裝載機而不是作爲yncTask在後臺加載你的數據。否則,您必須管理遊標,與UI線程正確同步,並確保所有查詢都發生在後臺線程上。此外,利用現在反對的startManagingCursor和managedQuery方法是非常氣餒;他們放慢了你的應用程序,並且可以讓它停下來。

Android 3.0的推出Loader和LoaderManager類來幫助簡化流程。這兩個類都可以在Android支持庫中使用,該支持庫支持Android 1.6以上的所有Android平臺。

裝載機確保所有遊標操作完成異步,從而消除阻塞UI線程的可能性。此外,當由LoaderManager管理時,Loaders會在整個活動實例中保留其現有的光標數據(例如,由於屏幕旋轉而重啓時),因此可以避免不必要的光標,從而可能會導致昂貴的重新查詢。作爲額外的好處,Loaders具有足夠的智能,可以監視底層數據源的更新情況,在數據更改時自動重新查詢。

看看這個博客有大約裝載機 http://www.androiddesignpatterns.com/2012/07/understanding-loadermanager.html

或訪問官方文檔Android開發者的更多信息: http://developer.android.com/guide/components/loaders.html

+0

噢,這對我來說非常困難!我想我必須在加載程序和數據庫之間有一個ContentProvider,對吧?難道,裝載機只能用於從UI緩存數據嗎?我想緩存URL中的一些數據,但不明白我如何獲得ContentProvider,在這裏下載和緩存數據。也許CursorLoader用於UI數據,我可以使用AsyncTaskLoader(而不是我的AsyncTask)? – lis

+0

嗯,是的,ContentProvider作爲實際的sqlite數據庫的包裝。但是contentProvider不會爲你下載數據。爲此,你可能想寫一個服務。 –