2012-05-04 36 views
3

我正在寫一個使用sqlite的android應用程序。有很多活動和一項服務。我使用來自多個線程的數據庫。它完美的Android 2.X,但一旦我在Android 3.X運行它,它總是拋出這個錯誤,Force Close多線程的Android sqlite

05-04 22:17:04.815: I/SqliteDatabaseCpp(8774): sqlite returned: error code = 5, msg = database is locked, db=/data/data/xxx/databases/im 
05-04 22:17:04.815: E/SqliteDatabaseCpp(8774): sqlite3_open_v2("/data/data/xxx/databases/im", &handle, 6, NULL) failed 
05-04 22:17:04.835: E/SQLiteDatabase(8774): Failed to open the database. closing it. 
05-04 22:17:04.835: E/SQLiteDatabase(8774): android.database.sqlite.SQLiteDatabaseLockedException: database is locked 
05-04 22:17:04.835: E/SQLiteDatabase(8774):  at android.database.sqlite.SQLiteDatabase.dbopen(Native Method) 
05-04 22:17:04.835: E/SQLiteDatabase(8774):  at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:983) 
05-04 22:17:04.835: E/SQLiteDatabase(8774):  at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:956) 
05-04 22:17:04.835: E/SQLiteDatabase(8774):  at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:1021) 
05-04 22:17:04.835: E/SQLiteDatabase(8774):  at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:790) 
05-04 22:17:04.835: E/SQLiteDatabase(8774):  at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:221) 
05-04 22:17:04.835: E/SQLiteDatabase(8774):  at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:149) 

任何人都知道它爲什麼會發生,以及如何解決呢?

我已經研究在互聯網和大多數人建議:僅對應用

  1. 使用一個數據庫連接。如何確保它?我想共享服務和活動的數據庫連接。我應該通過創建一個公共靜態DB變量來完成嗎?
  2. ContentProvider - 我在代碼中使用複雜的SQL語句(如加入少量表格,臨時表格)。是否有可能在ContentProvider中運行這些複雜的SQL語句?


    謝謝大家。最後,(1)對我很好。但我仍然想知道爲什麼Android 2.X沒有這個問題。
+0

1)僅在所有訪問都是在同一進程中發生時纔有效,2)只要您需要插入/查詢/更新/刪除即可使用,但複雜查詢看起來很難看,因爲您僅限於http://開發人員.android.com/reference/android/content/ContentResolver.html接口 – zapl

+0

謝謝zapl,數據庫不與其他應用程序共享。我認爲(1)對我有好處。你有什麼想法爲什麼Android 2.X沒有這個問題? –

+1

你應該去這個鏈接http://stackoverflow.com/questions/7930139/android-databse-locked –

回答

5

1號是答案。我有幾個堆答案,關於究竟如何做到這一點的博客文章:

What are the best practices for SQLite on Android?

http://touchlabblog.tumblr.com/post/24474750219/single-sqlite-connection

2號是一個很多額外的工作和不必要的。 ContentProvider存在,因此您可以與其他應用程序共享數據。它用於管理數據庫連接,因爲人們不知道Sqlite和Android如何協同工作。

+0

謝謝凱文加利根,我已閱讀您的帖子。我學到了很多 - http://stackoverflow.com/questions/2493331/what-is-best-practice-with-sqlite-and-android/3689883#3689883。我正在嘗試解決方案(1)。如果解決方法(1)失敗,我將學習ormlite。謝謝! –

+3

ORMLite很好,但對於從多線程訪問數據庫來說完全沒有必要。只需要一個靜態的SQLiteOpenHelper實例,或者在應用程序中保留一個實例n實例。如果您只有一個實例,則永遠不會鎖定數據庫問題。 –

+0

感謝Kevin,ORMLite反正很棒 –

3

我建議你只要可以,就用ContentProviderLoaderManager。它能夠自動在後臺執行查詢。

+0

感謝您的建議,但它需要很多額外的工作,數據庫不會與其他應用程序共享。我認爲解決方案(1)對我更好。如果(1)有效,我會考慮你的建議解決方案。謝謝 –

+2

我知道很多喜歡ContentProvider的人,但對於多線程數據庫訪問來說,它並不是必需的。如果你只是使用它,它不需要。但是,如果您喜歡ContentProvider,請使用它。不過,看起來像是對我來說額外的工作。 –