我使用greenDao作为ORM,现在我正试图让应用程序多线程,因为性能问题。 以下是我打开连接的方式:
class appClass extends Application{
@Override
public void onCreate(){
DaoMaster.OpenHelper helper = new DaoMaster.OpenHelper(this, "my-db", null);
final SQLiteDatabase db = helper.getWritableDatabase();
final DaoMaster daoMaster = new DaoMaster(db);
daoSession = daoMaster.newSession();
}
有时应用程序会崩溃
.SQLiteException:无法执行此语句,因为它可能 修改数据库,但连接是只读的。
这里是Stacktrace:
java.lang.RuntimeException:无法恢复活动 {} com.my.app.android/com.my.app.android.ui.ListActivity: android.database.sqlite.SQLiteException:无法执行此语句 因为它可能会修改数据库,但连接是只读的。 在android.app.ActivityThread.performResumeActivity(ActivityThread.java:3581) 在android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3621) 在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1638) 在android.os.Handler.dispatchMessage(Handler.java:106) 在android.os.Looper.loop(Looper.java:164) 在android.app.ActivityThread.main(ActivityThread.java:6494) at java.lang.reflect.Method.invoke(Native Method) 在com.android.internal.os.RuntimeInit $ MethodAndArgsCaller.run(RuntimeInit.java:438) 在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)引起:android.database.sqlite.SQLiteException:无法执行 此语句因为它可能会修改数据库但连接 是只读的。 在android.database.sqlite.SQLiteConnection.throwIfStatementForbidden(SQLiteConnection.java:1026) 在android.database.sqlite.SQLiteConnection.executeForChangedRowCount(SQLiteConnection.java:730) 在android.database.sqlite.SQLiteSession.executeForChangedRowCount(SQLiteSession.java:754) 在android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:64) 在android.database.sqlite.SQLiteDatabase.executeSql(SQLiteDatabase.java:1754) 在android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1682) 在com.my.app.android.orm.generated.ObjektDao.deleteOPTempTable(ObjektDao.java:479) 在com.my.app.android.orm.generated.ObjektDao.reBuildOPTempTable(ObjektDao.java:544) 在com.my.app.android.TempTablesUtils.checkTempTables(TempTablesUtils.java:132) 在com.my.app.android.ui.ListActivity.onRestart(ListActivity.java:94) 在android.app.Instrumentation.callActivityOnRestart(Instrumentation.java:1344) 在android.app.Activity.performRestart(Activity.java:7088) 在android.app.Activity.performResume(Activity.java:7099) 在android.app.ActivityThread.performResumeActivity(ActivityThread.java:3556) ......还有8个
为什么在这种情况下连接是只读的?
答案 0 :(得分:0)
可能你已经拥有了可能尚未关闭的联系。
更具体地说,该消息是从 SQLiteConnection.java 行709-714内发出的: -
private void throwIfStatementForbidden(PreparedStatement statement) {
if (mOnlyAllowReadOnlyOperations && !statement.mReadOnly) {
throw new SQLiteException("Cannot execute this statement because it "
+ "might modify the database but the connection is read-only.");
}
}
该文件中的评论包括: -
/ ** *表示SQLite数据库连接。 *每个连接 包装本机
sqlite3
对象的实例。 ** 启用数据库连接池时,可能有多个 active *连接到同一个数据库。否则有 通常每个数据库只有一个*连接。 *
*当 SQLite WAL功能已启用,多个阅读器和一个编写器*可以 同时访问数据库。没有WAL,读者和作家* 相互排斥。 *
* *所有权和并发性 保证
**连接对象不是线程安全的。 根据需要获取它们以执行数据库操作 然后回到游泳池。在任何*给定时间,连接是 由@@link SQLiteSession} *对象拥有和使用 {@link SQLiteConnectionPool}。这些课程负责 序列化操作以防止并发*使用a 连接。 *
*拥有单一所有者的保证 允许这个类在没有锁的情况下实现* 简化资源管理。 *
* *封装 保证
**连接对象对象拥有所有 与SQLite相关的本机*对象 连接。更重要的是,系统中没有其他对象 能够获得*那些本机对象的句柄。 因此,当连接关闭时,我们不需要 担心其他组件可能引用*它的内容 关联的SQLite状态 - 没有。 *
*封装 是确保连接对象的生命周期没有的原因 成为一个折磨混乱的终结者和参考*队列。 *
* * @hide * /