我在我的应用程序中提供了一些导出/导入功能,现在我看到,如果在较新的android版本中导入旧的导出操作,则会出现问题,因为在运行android 9或更高版本的许多手机上,SQLite
数据库请勿使用journal_mode
WAL
,而不要使用旧手机上的DELETE
。
信息/执照:
SQLiteOpenHelper
内)设置手动日记模式DELETE
模式),因此在手机上还原旧备份效果很好DELETE
模式的电话上,恢复的备份使我的应用程序崩溃,因为我的应用程序数据库似乎为空-我不在乎。 f当然,照顾一个空数据库并不能解决问题,因为我需要导入的数据... 问题:
上面引出了以下三个问题:
WAL
还是DELETE
?*.db
文件的模式?*.db
文件更改此模式?我不想要的
我不想完全禁用我的应用程序内的WAL
,我更喜欢一些基于迁移的解决方案
答案 0 :(得分:2)
如何确定当前手机默认使用WAL还是DELETE?
如果设备使用Android 9+,则如果正确实现,则应默认为WAL模式。但是,设备提供商可以提供自定义/旧版实现。因此,您需要按照下面显示/回答的步骤进行检查(实际上,使用下面的方法无需检查)。
崩溃的原因可能是您没有备份在WAL模式处于活动状态时存在的其他-wal和-shm文件。
在实际进行备份之前,我使用下面的代码
:-
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方法isWriteAheadLoggingEnabled返回true或false。
关于:-
如何为给定的* .db文件更改此模式?
如果使用Android SDK,则可以使用SQLiteDatabase方法enableWriteAheadLogging或disableWriteAheadLogging,也可以通过journal_mode pragma进行设置,但要注意何时可以使用承担。 Write-Ahead Logging