问题描述
在这少数启用了 WAL(预写日志记录)的 Android 设备上,我确实遇到了很多数据库备份/恢复问题.创建这样的数据库后是否可以关闭它?
I do have a lot of problems with database backup/restore on these few Android devices that do have WAL (write ahead logging) enabled. Is it possible to switch that off after such a database has been created?
我的想法是:
1.) 使此功能适用于旧版 Android 设备的包装器:
1.) A wrapper that makes this work on older Android devices:
public class SQLiteDatabaseWalWrapper {
private boolean available;
private Method disableWriteAheadLogging;
private Method enableWriteAheadLogging;
private Method isWriteAheadLoggingEnabled;
private SQLiteDatabase sqliteDatabase;
public SQLiteDatabaseWalWrapper(final SQLiteDatabase sqliteDatabase) {
this.sqliteDatabase = sqliteDatabase;
available = false;
try {
disableWriteAheadLogging = SQLiteDatabase.class.getMethod("disableWriteAheadLogging");
enableWriteAheadLogging = SQLiteDatabase.class.getMethod("enableWriteAheadLogging");
isWriteAheadLoggingEnabled = SQLiteDatabase.class.getMethod("isWriteAheadLoggingEnabled");
available = true;
} catch (NoSuchMethodException noSuchMethodException) {
}
}
public boolean checkAvailable() {
return available;
}
public void disableWriteAheadLogging() {
if (disableWriteAheadLogging != null) {
try {
disableWriteAheadLogging.invoke(sqliteDatabase);
} catch (IllegalAccessException illegalAccessException) {
} catch (IllegalArgumentException illegalArgumentException) {
} catch (InvocationTargetException invocationTargetException) {
}
}
}
public boolean enableWriteAheadLogging() {
boolean result = false;
if (enableWriteAheadLogging != null) {
try {
result = (Boolean) enableWriteAheadLogging.invoke(sqliteDatabase);
} catch (IllegalAccessException illegalAccessException) {
} catch (IllegalArgumentException illegalArgumentException) {
} catch (InvocationTargetException invocationTargetException) {
}
}
return result;
}
public boolean isWriteAheadLoggingEnabled() {
boolean result = false;
if (isWriteAheadLoggingEnabled != null) {
try {
result = (Boolean) isWriteAheadLoggingEnabled.invoke(sqliteDatabase);
} catch (IllegalAccessException illegalAccessException) {
} catch (IllegalArgumentException illegalArgumentException) {
} catch (InvocationTargetException invocationTargetException) {
}
}
return result;
}
}
2.) 在带有 AsyncTask 的扩展应用程序中,我将发出一个完整的检查点并关闭 WAL:
2.) Within an extended Application with AsyncTask I will issue a FULL checkpoint and switch WAL off:
public class MyApplication extends Application {
private class MyAsyncTask extends AsyncTask<Void, Void, Boolean> {
@Override
protected Boolean doInBackground(final Void... voids) {
// Make a full checkpoint
sqliteDatabase.execSQL("PRAGMA wal_checkpoint(FULL);");
// switch WAL off
sqliteDatabaseWalWrapper.disableWriteAheadLogging();
}
@Override
protected void onPostExecute(final Boolean result) {
}
}
private Context context;
private SQLiteDatabase sqliteDatabase;
private SQLiteDatabaseWalWrapper sqliteDatabaseWalWrapper;
private MySQLiteOpenHelper sqliteOpenHelper;
private MyAsyncTask task;
@Override
public void onCreate() {
super.onCreate();
context = getApplicationContext();
sqliteOpenHelper = new MySQLiteOpenHelper(context);
if (sqliteOpenHelper != null) {
sqliteDatabase = sqliteOpenHelper.getWritableDatabase();
if (sqliteDatabase != null) {
if (Build.VERSION.SDK_INT >= 16) {
sqliteDatabaseWalWrapper = new SQLiteDatabaseWalWrapper(sqliteDatabase);
if (sqliteDatabaseWalWrapper != null && sqliteDatabaseWalWrapper.checkAvailable() && sqliteDatabaseWalWrapper.isWriteAheadLoggingEnabled()) {
task = new MyAsyncTask();
task.execute();
}
}
}
}
}
@Override
public void onTerminate() {
if (sqliteDatabase != null) {
sqliteDatabase.close();
}
if (sqliteOpenHelper != null) {
sqliteOpenHelper.close();
}
super.onTerminate();
}
}
这行得通吗?这会删除 SQLite 在启用 WAL 的数据库上创建的各种附加文件吗?这会返回到 Android 文档中描述的单个数据库文件吗?
Will this work? Will this delete the various additional files that SQLite does create on WAL-enabled databases? Will this lead back to that single database file that's described in the Android docs?
推荐答案
你可以通过这行代码将数据库模式更改为 TRUNCATE mote:
You can change database mode to TRUNCATE mote by this line of code:
setJournalMode(RoomDatabase.JournalMode.TRUNCATE)
这篇关于是否可以在 Android SQLite 数据库上禁用 WAL?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!