我们有一个奇怪的错误。如果电池电量耗尽,我们的应用程序将丢失它的数据(存储在SQLite中),但如果我们强行终止应用程序然后电池电量耗尽则不会。
我们不确定是什么原因引起的。
编辑1:
什么意味着放松数据?
如何存储对象:
public Void perform(SQLiteDatabase db) {
final ConfigEntry entry = new ConfigEntry(property, value);
if(contains(property)) {
db.update(ConfigEntry.TABLE_NAME, databaseAdapter.convertToContentValues(entry), ConfigEntry.COLUMN_NAME + " = ?", new String[] { property });
} else {
db.insertOrThrow(ConfigEntry.TABLE_NAME, null, databaseAdapter.convertToContentValues(entry));
}
return null;
}
});
所以基本上调用了db.insertOrThrow。
这是我们初始化数据库的方式:
public S doInTransaction(TransactionTask task) {
DatabaseHelper mDbHelper = DatabaseHelper.getInstance(mContext);
SQLiteDatabase mDb = mDbHelper.getWritableDatabase();
mDb.setLockingEnabled(true);
mDb.beginTransaction();
try {
S result = task.perform(mDb);
mDb.setTransactionSuccessful();
return result;
} finally {
mDb.endTransaction();
}
}
答案 0 :(得分:1)
问题是你正在使用beginTransaction()
。如果您有来电beginTransaction()
,则需要致电:
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
以下或您的数据将不会保存。原因在于sqlite manual
并且您的数据未保存的原因是,如果您启动了事务并且由于系统试图关闭它而未调用db.setTransactionSuccessful();
,则不会保存数据。但是,finally{}
可能仍会被调用,但这不会改变未调用db.setTransactionSuccessful();
的事实。
答案 1 :(得分:1)
我不确定,但我希望我能提供一些问题或灵感来深入挖掘:
您是否监控过您的数据库是否经历了完整的初始创建过程,或者是否存在表格但只缺少用户名?您可以从设备下载数据库文件并在PC上的SQLite工具中查看内容吗?
您在doInTransaction()
内打开数据库,但不要在那里关闭它:
public S doInTransaction(TransactionTask task) {
DatabaseHelper mDbHelper = DatabaseHelper.getInstance(mContext);
SQLiteDatabase mDb = mDbHelper.getWritableDatabase();
//mDb.setLockingEnabled(true); // true is default, so it can be removed
mDb.beginTransaction();
S result = null;
try {
result = task.perform(mDb);
mDb.setTransactionSuccessful();
} finally {
// rolls back if setTransactionSuccessful() wasn't called
mDb.endTransaction();
mDb.close();
}
return result;
}
您完全确定使用相同的数据库吗?我问,因为我曾经看到有人使用时间戳作为数据库名称的一部分。
您没有错误地创建in-memory database?
设备有多种不同的方式可以使电池电量不足:它可能会死机或者设法实际关闭紧急电源。哪一个是这样的?您是否有任何日志记录可能会提供应用程序启动时的内容?
总结:我怀疑原因在于您提供的代码,正如您所提到的,代码仅在按下按钮时执行。这留下了上述问题需要进一步调查(当然,有些我可能会错过......)。
答案 2 :(得分:0)
非常感谢所有的帮助,我们终于找到了答案。
我们正在使用用户密码加密我们的数据库,并使用设备的 MAC地址来保存密码。
发生的事情是,当用户在启动后耗尽电池时,当我们的应用程序运行时,我们请求MAC地址失败,因为网卡仍处于禁用状态。在那种情况下,我们创建了一个新的盐,当尝试读取数据库时将失败。