【发布时间】:2022-01-10 07:19:18
【问题描述】:
我一直在努力让我的数据库备份工作,但我已经到了不知道该怎么做的地步。
基本上,首先应用程序打开一个登录活动,用户登录并从 Firebase 存储下载他们的数据库文件(如果存在),然后应用程序导航到 MainActivity。
在 MainActivity 中,我调用了一个将用户的数据库文件发送到 Firebase 存储的方法。我试图通过关闭数据库来管理该过程,但由于我无法修复“E/ROOM:无效跟踪器被初始化两次:/。”的错误,所以我找到了使用检查点的答案(Backup Room database)。现在我实现了强制检查点方法。
(MarkerDao)
@RawQuery
int checkpoint(SupportSQLiteQuery supportSQLiteQuery);
(MarkerRepository)
public void checkPoint(){
Thread thread= new Thread(() -> markerDao.checkpoint(new SimpleSQLiteQuery("pragma wal_checkpoint(full)")));
thread.start();
}
(ViewModel)
public void setCheckpoint(){
repository.checkPoint();
}
(Database back-up method in the MainActivity)
private void copyDbToFirebase(){
String currentDBPath = "/data/data/"+ getPackageName() + "/databases/locations_table";
File dbBackupFile = new File(currentDBPath);
if (dbBackupFile.exists()){
markerViewModel.setCheckpoint();
// create file from the database path and convert it to a URI
Uri backupDB = Uri.fromFile(new File(currentDBPath));
// Create a StorageReference
StorageReference dbReference = storageRef.child("users").child(userId).child("user database").child("locations_table");
// Use the StorageReference to upload the file
if (userId != null){
dbReference.putFile(backupDB).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
@Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Log.d(TAG, "onSuccess: "+4 + taskSnapshot);
Toast.makeText(getApplicationContext(), "Database copied to Firebase 4", Toast.LENGTH_LONG).show();
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.d(TAG, "onFailure: "+ e.getMessage());
}
});
}
}
}
如果用户注销,则“/data/data/”+ getPackageName() + “/databases/”中的文件将被删除,我已通过查看应用程序的数据库文件夹手动确认。
我的问题是,在删除数据库并有新用户登录后,以前的数据库数据仍然存在,但是当我手动检查应用程序的数据文件夹时,/databases/ 文件夹显示文件已被删除并且新的文件已创建,但它没有显示任何 WAL 或 SHM 文件,而且我还获得了在应用程序首次运行时创建的另一个数据库的数据,但该文件也未显示在 databases/ 文件夹中。
谁能解释为什么该文件夹不显示应该存在的文件,应用程序在哪里获取已删除的数据以及如何修复它。
编辑:我的应用程序有多个 Room 数据库,我刚刚意识到删除文件后所有数据仍然可读。
删除数据库文件的方法
private boolean deleteDatabaseFiles(File path) {
if(path.exists() ) {
File[] files = path.listFiles();
for(int i=0; i<files.length; i++) {
if(files[i].isDirectory()) {
deleteDatabaseFiles(files[i]);
}
else {
files[i].delete();
}
}
}
return true;
}
【问题讨论】:
标签: java android database sqlite android-room