Android 房间数据库:在RoomOpenHelper.checkIdentity()上崩溃

Android 房间数据库:在RoomOpenHelper.checkIdentity()上崩溃,android,sqlite,android-room,android-architecture-components,Android,Sqlite,Android Room,Android Architecture Components,我有一个遗留应用程序,它正在使用Room,在执行第一个数据库查询时,无论查询是什么,它都会崩溃 java.lang.RuntimeException: Unable to start service com.someco.android.nettasks.PushQueueService@24ccdca6 with Intent { cmp=com.someco.android/.nettasks.PushQueueService }: android.database.sqlite.SQL

我有一个遗留应用程序,它正在使用Room,在执行第一个数据库查询时,无论查询是什么,它都会崩溃

  java.lang.RuntimeException: Unable to start service com.someco.android.nettasks.PushQueueService@24ccdca6 with Intent { cmp=com.someco.android/.nettasks.PushQueueService }: android.database.sqlite.SQLiteException: Cannot execute this statement because it might modify the database but the connection is read-only.
      at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3439)
      at android.app.ActivityThread.access$2200(ActivityThread.java:181)
      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1572)
      at android.os.Handler.dispatchMessage(Handler.java:102)
      at android.os.Looper.loop(Looper.java:145)
      at android.app.ActivityThread.main(ActivityThread.java:6117)
      at java.lang.reflect.Method.invoke(Native Method)
      at java.lang.reflect.Method.invoke(Method.java:372)
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
   Caused by: android.database.sqlite.SQLiteException: Cannot execute this statement because it might modify the database but the connection is read-only.
      at io.requery.android.database.sqlite.SQLiteConnection.throwIfStatementForbidden(SQLiteConnection.java:1091)
      at io.requery.android.database.sqlite.SQLiteConnection.executeForChangedRowCount(SQLiteConnection.java:755)
      at io.requery.android.database.sqlite.SQLiteSession.executeForChangedRowCount(SQLiteSession.java:764)
      at io.requery.android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:71)
      at io.requery.android.database.sqlite.SQLiteDatabase.executeSql(SQLiteDatabase.java:1867)
      at io.requery.android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1808)
      at android.arch.persistence.room.RoomOpenHelper.createMasterTableIfNotExists(RoomOpenHelper.java:131)
      at android.arch.persistence.room.RoomOpenHelper.checkIdentity(RoomOpenHelper.java:107)
      at android.arch.persistence.room.RoomOpenHelper.onOpen(RoomOpenHelper.java:100)
      at io.requery.android.database.sqlite.RequerySQLiteOpenHelperFactory$CallbackSQLiteOpenHelper.onOpen(RequerySQLiteOpenHelperFactory.java:67)
      at io.requery.android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:283)
      at io.requery.android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:174)
      at io.requery.android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:44)
      at com.someco.android.dmodel.OurDB.writableDb(OurDB.java:363)
      at com.someco.android.nettasks.PushQueueService.startExecution(PushQueueService.java:202)
      at com.someco.android.nettasks.PushQueueService.onStartCommand(PushQueueService.java:157)
      at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3422)
      at android.app.ActivityThread.access$2200(ActivityThread.java:181)
      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1572)
      at android.os.Handler.dispatchMessage(Handler.java:102)
      at android.os.Looper.loop(Looper.java:145)
      at android.app.ActivityThread.main(ActivityThread.java:6117)
      at java.lang.reflect.Method.invoke(Native Method)
      at java.lang.reflect.Method.invoke(Method.java:372)
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
根据我对调试器的调查,现在发生的事情是,在sqlite本身中调用
sqlite3\u stmt\u readonly()
时出现了一些争用问题。这是导致崩溃的实际查询,来自
RoomOpenHelper\createMastertableIfNotExists

CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)
RoomOpenHelper#onCreate
中,成功创建了表。语句似乎被编译了两次,并在这两次中检查了只读状态:

  • 一旦进入
    SQLiteProgram
    的构造函数(通过
    SQLiteStatement
  • 一旦进入
    SQLiteConnection#executeForChangedRowCount
发生的情况是,为第一个获取的连接以更大的权限打开(
6
,对于我来说-
1
是表示只读状态的位),并且正确评估为非只读。这意味着第二个语句编译的连接是用只读标志请求的(
5
,对我来说)。崩溃发生的原因是由于某种原因,查询再次被计算为非只读


这一次我完全不知所措。为什么会崩溃?为什么同一条语句有时是只读的,而其他时候不是只读的?

问题是room
1.0.0
不支持预写日志。我删除了在应用程序中启用它的一行:

db.getOpenHelper().setWriteAheadLoggingEnabled(true);
WAL在版本
1.1.0-alpha2
中受支持。在试用了新的alpha之后,一切都正常了,所以更改日志为我指出了答案。我对这个问题有一个简短的评论