这里有几个关于 stackoverflow 的问题,人们使用 BackupAgents 将应用程序数据与谷歌云同步(见这里)。在我的具体情况下,由于或多或少敏感数据的性质,要求更具限制性。一切都只能存储在设备本身上,并且应用程序不得连接到互联网。
主 Activity 包含一个 ViewPager,它承载了一些 ListFragment。每个 ListFragment 都有自己的 Loader,它在 SimpleCursorAdapter 类中交换光标。
在备份和恢复数据库之前,我使用以下命令销毁加载程序:
getLoaderManager().destroy(LOADER_ID);
我的备份功能与此anwser类似:
final String inFileName = "/data/data/<your.app.package>/databases/foo.db";
File dbFile = new File(inFileName);
FileInputStream fis = new FileInputStream(dbFile);
String outFileName = Environment.getExternalStorageDirectory()+"/database_copy.db";
// Open the empty db as the output stream
OutputStream output = new FileOutputStream(outFileName);
// Transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[1024];
int length;
while ((length = fis.read(buffer))>0){
output.write(buffer, 0, length);
}
// Close the streams
output.flush();
output.close();
fis.close();
恢复功能类似,它将数据库从 sdcard 复制回内部应用程序文件夹,停止加载程序并覆盖数据库文件。
public static void restore(Context context) throws IOException {
if (externalStorageIsWriteable()) {
// getBackupDir() is a path to the folder on the sdcard
File fileBackup = new File(getBackupDir(), WineSQLiteHelper.DB_NAME);
if (!fileBackup.exists()) {
throw new IOException("File not found");
}
File importFile = getImportDatabase();
try {
FileUtils.copyFile(fileBackup, importFile);
MySQLiteHelper dbHelper = new MySQLiteHelper(context);
dbHelper.close();
dbHelper = null;
File file = new File(Environment.getDataDirectory() + "/data/"
+ PACKAGE + "/databases/" + WineSQLiteHelper.DB_NAME);
FileUtils.copyFile(importFile, file);
// Remove temporary import file.
importFile.delete();
} catch (IOException e) {
throw e;
}
} else {
throw new IOException("External Storage not writeable");
}
}
但是不知何故,在我覆盖了数据库文件并收到了一些之后,MainActivity 被重新创建了
SQLiteException: no such column
我的猜测是,可能仍然有与数据库的开放连接,但我不确定,因为这是我第一次必须如此密切地使用数据库。
如何正确关闭 ContentProvider 的所有数据库连接?我在文档中找不到任何关于此的内容。这是必要的吗?
如何正确恢复数据库?