在这几个启用了WAL(提前写入日志记录)的Android设备上,我确实遇到了很多数据库备份/恢复问题。在创建这样的数据库之后是否可以关闭它?
我的想法是:
1。)一个包装器,可以在较旧的Android设备上运行:
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:
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文档中描述的单个数据库文件吗?
答案 0 :(得分:1)
在数据库上执行PRAGMA journal_mode=DELETE
应删除Wal模式并返回正常的操作方法。
此处提供完整文档:http://www.sqlite.org/wal.html
答案 1 :(得分:0)
以编程方式我们可以启用和禁用WAL模式。它自API级别11以来一直存在
请参阅此文档以获取更多信息
答案 2 :(得分:0)
setJournalMode(RoomDatabase.JournalMode.TRUNCATE)