在这些启用了 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 文档中描述的单个数据库文件吗?