所以我試着使用單獨的線程來保存數據到數據庫,但它會導致異常:安卓:保存在單獨的線程中的數據庫將導致數據庫異常關閉
java.lang.IllegalStateException:數據庫無法打開
我想這是不是一個Loader
,因爲我不需要任何導致光標,它只是爲了節省我的數據的任務。保存到db代碼看起來如下:
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
dbHelper.saveMessages(messages);
}
});
thread.setPriority(Thread.MIN_PRIORITY);
thread.start();
如果我從一個線程刪除這個數據庫操作一切都很好,但它會導致UI滯後。如果我試圖從單獨的線程讀取數據庫,會發生同樣的情況。
這是一個DB編寫代碼的一部分:
SQLiteDatabase db = dbAdapter.getWritableDatabase());
try {
if (existingMessage != null)
insertId = db.update(Tables.Messages.TABLE_NAME, values, Tables.Messages.SERVER_ID + "=?", new String[]{String.valueOf(message.serverId)});
else
insertId = db.insertOrThrow(Tables.Messages.TABLE_NAME, null, values);
} catch (Exception e) {
e.printStackTrace();
}
其實例外發生在db.update(),或在db.insertOrThrow()線。它不保證拋出異常,但它不時。它可以寫入例如5個對象,然後在6日失敗。
我在做什麼錯誤或最新SQLiteOpenHelper錯誤? 完整的異常日誌:
10-30 22:34:52.746 10431-10536/com.myapp W/System.err﹕ java.lang.IllegalStateException: database not open
10-30 22:34:52.746 10431-10536/com.myapp W/System.err﹕ at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1224)
10-30 22:34:52.746 10431-10536/com.myapp W/System.err﹕ at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1184)
10-30 22:34:52.746 10431-10536/com.myapp W/System.err﹕ at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1264)
10-30 22:34:52.746 10431-10536/com.myapp W/System.err﹕ at com.myapp.db.DatabaseHelper.saveMessages(DatabaseHelper.java:478)
10-30 22:34:52.746 10431-10536/com.myapp W/System.err﹕ at com.myapp.db.DatabaseHelper.requestMessages(DatabaseHelper.java:1245)
10-30 22:34:52.746 10431-10536/com.myapp W/System.err﹕ at com.myapp.activity.LoginActivity$9.run(LoginActivity.java:425)
10-30 22:34:52.746 10431-10536/com.myapp W/System.err﹕ at java.lang.Thread.run(Thread.java:1096)
UPDATE:
我會發現,它的所有關於從數據庫中實際讀取。在我的代碼中,我首先從db中讀取以確保沒有這樣的記錄。之後,我決定要做什麼 - 插入或更新。這個問題發生在可讀數據庫中。在打開db進行讀取之後,下一行應該從db中讀取,它顯示爲「未打開」。沒有線程可供閱讀,一切都發生在一個線程中:第一次讀取然後寫入。然而閱讀隨機失敗。所以它不像我之前提到的那樣寫。
是什麼在你的代碼它發生的確切堆棧跟蹤和在哪裏呢?發佈'saveMessages()'代碼。 – laalto 2014-10-30 20:04:06
你可能不是非常小心的多線程。看看[這個問題](http://stackoverflow.com/questions/2493331/what-are-the-best-practices-for-sqlite-on-android/3689883)。它的一些答案可能會有所幫助。 – Jakar 2014-10-30 20:32:46
其實我不知道你爲什麼不使用AtomicInteger而不是鎖定一個虛假的對象只是爲了counter ++或 - 。無論如何,我正在使用Dmytro Danylyk的解決方案。然而,我的問題不是關於多線程,因爲沒有其他線程使用db來同時讀取或寫入。 – Stan 2014-10-30 20:50:18