这里有一些关于stackoverflow的问题,其中人们使用BackupAgents将应用数据与googles cloud同步(参见here)。在我的具体情况下,由于或多或少敏感数据的性质,要求更具限制性。所有内容必须只存储在设备上,并且应用程序不得连接到互联网。
主Activity包含一个ViewPager,它承载一些ListFragments。每个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复制回内部app文件夹,停止加载器并覆盖数据库文件。
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的所有数据库连接?我在文档中找不到任何关于此的内容。这有必要吗?
如何正确恢复数据库?