Ich habe eine schreibgeschützte Datenbankverbindung. Beim Lesen von Daten aus der Datenbank mit einer Abfrage SELECT
wird manchmal ein SQLiteReadOnlyDatabaseException
ausgelöst.Versuch, eine Readonly-Datenbank zu schreiben ... aber ich bin nicht
Ich öffne die Verbindung wie folgt aus:
return SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READONLY);
Die Abfrage ist:
Select * FROM BudgetVersions WHERE entityId = ?
Ich lese Daten aus der Datenbank db.rawQuery()
verwendet wird, wie folgt aus:
String query = ...;
Cursor c = db.rawQuery(query, new String[]{ activeBudgetId });
try {
if (c.moveToFirst()) {
bv.versionName = c.getString(c.getColumnIndexOrThrow("versionName"));
return bv;
} else {
return null;
}
} finally {
c.close();
}
Sehr selten , Bekomme ich einen solchen Crash, innerhalb des Anrufs c.moveToFirst()
:
Caused by: android.database.sqlite.SQLiteReadOnlyDatabaseException: attempt to write a readonly database (code 776)
at android.database.sqlite.SQLiteConnection.nativeExecuteForCursorWindow(Native Method)
at android.database.sqlite.SQLiteConnection.executeForCursorWindow(SQLiteConnection.java:845)
at android.database.sqlite.SQLiteSession.executeForCursorWindow(SQLiteSession.java:836)
at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:62)
at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:144)
at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:133)
at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:197)
at android.database.AbstractCursor.moveToFirst(AbstractCursor.java:237)
Als Workaround könnte ich stattdessen eine beschreibbare Datenbankverbindung versuchen, aber ich würde gerne wissen, warum der Absturz passiert.
Die Tabelle aus lese ich eine Standard-SQLite Tabelle:
CREATE TABLE BudgetVersions (
entityId VARCHAR PRIMARY KEY NOT NULL UNIQUE,
budgetId VARCHAR NOT NULL,
versionName VARCHAR NOT NULL,
dateFormat VARCHAR,
currencyFormat VARCHAR,
lastAccessedOn DATETIME,
isTombstone BOOL NOT NULL,
deviceKnowledge NUMERIC NOT NULL
);
ich den Absturz sowohl auf ein KitKat-Emulator und ein Gerät passieren gesehen habe laufen Lollipop.
Es gibt eine separate beschreibbare Verbindung offen zu derselben Datenbank zugleich von einem WebView gehört. Die Datenbank wird durch JavaScript-Code im WebView aktualisiert und in der nativen Android/Java-Schicht mit dieser schreibgeschützten Verbindung gelesen.
Ich erwarte, dass dies die ultimative Ursache des Problems sein kann, aber ich würde gerne im Detail verstehen, warum eine schreibgeschützte Verbindung eine separate beschreibbare Verbindung stören würde.
Ich bin mir bewusst, dass der allgemeine Ratschlag ist, eine einzelne Verbindung mit der Datenbank zu verwenden, aber da die beschreibbare Verbindung im Besitz der WebView
ist, habe ich keinen einfachen Zugriff darauf aus dem Java-Code.
Beachten Sie, dass 'cwac-loaderex' seit geraumer Zeit nicht mehr verwendet wird. Ist das ein Crash, den Sie während der Entwicklung oder nur in der Produktion sehen? Beachten Sie, dass 'getCount()' tatsächlich die SQL-Abfrage ausführt, die Sie dem Loader zum Laden gegeben haben, da 'rawQuery()'/'query()' einen 'Cursor' zurückgibt, aber die Abfrage nicht sofort ausführt. – CommonsWare
Die Erwähnung von Loadern und CWAC-LoaderEx wurde entfernt. Das Problem tritt auch ohne sie auf. Den Absturz beobachtet man während der Entwicklung. –
Ich würde sagen, es ist ein Fehler in wie SQLlite eine Datenbankinstanz basierend auf den Flags zurückgibt, möglicherweise im Zusammenhang mit Multithreading. Ich würde annehmen, zu versuchen, eine Singleton-Instanz der schreibbaren Datenbank für alle Ihre Operationen zu halten sollte es lösen (auch alle Ihre Verbindungen in Lese-Schreib-öffnen) – njzk2