我在我的应用程序中提供了一些导出/导入功能,现在我看到,如果在较新的Android版本中导入旧导出,这会导致问题,因为在许多运行Android 9或运行的手机上更高的是,SQLite
数据库确实使用journal_mode
WAL
代替DELETE
,它们在旧电话上使用。
Infos/Obersvations:
- 我没有在我的应用程序内设置手动日记帐模式(例如
SQLiteOpenHelper
内部( - 并非所有的Android 9手机都启用了此功能(我的S9运行派仍然使用
DELETE
模式(,因此在我的手机上还原旧备份非常好 - 在不使用
DELETE
模式的电话上,恢复的备份会崩溃我的应用程序,因为数据库似乎是我的应用程序空的 - 我不小心。f课程,关注空数据库并不能解决问题,因为我需要导入的数据...
问题:
上面导致以下3个问题:
- 默认情况下,我如何找出当前手机是否使用
WAL
或DELETE
? - 如何找出给定的
*.db
文件的模式? - 如何为给定的
*.db
文件更改此模式?
我不想要
我不想完全禁用我的应用程序中的WAL
,我确实更喜欢一些基于迁移的解决方案
如何默认情况下查找当前电话使用WAL还是删除?
如果设备使用Android 9 ,则应(如果正确实现(默认为WAL模式。但是,设备提供商可以提供自定义/旧版实现。因此,您需要按照下面显示的检查/回答(实际使用下面的方法,无需检查(。
崩溃的原因可能是您没有备份WAL模式处于活动状态时存在的附加-WAL和-SHM文件。
我在实际进行备份之前使用以下代码
- 显然 dbconstants.dbname 是数据库名称
- 数据库存储在默认位置( data/data/the_package/databases/(( (
: -
private void checkpointIfWALEnabled(Context context) {
final String TAG = "WALCHKPNT";
Cursor csr;
int wal_busy = -99, wal_log = -99, wal_checkpointed = -99;
SQLiteDatabase db = SQLiteDatabase.openDatabase(context.getDatabasePath(DBConstants.DATABASE_NAME).getPath(),null,SQLiteDatabase.OPEN_READWRITE);
csr = db.rawQuery("PRAGMA journal_mode",null);
if (csr.moveToFirst()) {
String mode = csr.getString(0);
//Log.d(TAG, "Mode is " + mode);
if (mode.toLowerCase().equals("wal")) {
csr = db.rawQuery("PRAGMA wal_checkpoint",null);
if (csr.moveToFirst()) {
wal_busy = csr.getInt(0);
wal_log = csr.getInt(1);
wal_checkpointed = csr.getInt(2);
}
//Log.d(TAG,"Checkpoint pre checkpointing Busy = " + String.valueOf(wal_busy) + " LOG = " + String.valueOf(wal_log) + " CHECKPOINTED = " + String.valueOf(wal_checkpointed) );
csr = db.rawQuery("PRAGMA wal_checkpoint(TRUNCATE)",null);
csr.getCount();
csr = db.rawQuery("PRAGMA wal_checkpoint",null);
if (csr.moveToFirst()) {
wal_busy = csr.getInt(0);
wal_log = csr.getInt(1);
wal_checkpointed = csr.getInt(2);
}
//Log.d(TAG,"Checkpoint post checkpointing Busy = " + String.valueOf(wal_busy) + " LOG = " + String.valueOf(wal_log) + " CHECKPOINTED = " + String.valueOf(wal_checkpointed) );
}
}
csr.close();
db.close();
}
这在任何一种情况下都可以使用,因为它可以通过检查数据库来有效地使用 -WAL 和> -SHM 文件(将它们清空(。因此,无需复制 -WAL 和 -SHM 文件,没有需要投入的出色交易。它适用于两种模式。
如何找出给定 *.db文件的模式?
行 csr = db.rawQuery("PRAGMA journal_mode",null);
是询问日记模式的行,还有sqlitedatabase方法iswriteaheadeaheadloggingEnabled返回true或false。
关于: -
如何为给定的 *.db文件更改此模式?
如果使用Android SDK,则可以使用sqlitedatabase方法enableWriteAheadLogging或disableWriteAheadLogging,也可以通过使用 Journal_mode pragma设置它,但请注意何时可以进行限制。写入记录