应用程序提供 Android 中已删除数据库文件的数据
Application gives data from deleted database file in Android
我一直在努力让我的数据库备份正常工作,但我已经到了不知道该做什么的地步。
基本上,首先应用程序打开一个登录 activity,用户登录并从 Firebase 存储下载他们的数据库文件(如果存在),然后应用程序导航到 MainActivity。
在 MainActivity 中,我调用了一个将用户的数据库文件发送到 Firebase 存储的方法。我试图通过关闭数据库来管理该过程,但由于我无法修复错误“E/ROOM:无效跟踪器已初始化两次:/。”,然后我找到了使用检查点的答案().现在我实现了强制检查点方法。
(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 文件,而且我还获取了应用程序首次运行时创建的另一个数据库的数据,但该文件也未显示在数据库/文件夹中。
任何人都可以解释为什么文件夹没有显示应该存在的文件,应用程序从哪里获取被删除的数据以及如何修复它。
编辑:我的应用程序有多个 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;
}
如果您使用的是完全相同的 RoomDatabase
对象,只需在同一对象上构建另一个对象即可防止显示缓存数据。我已经使用大大小小的多个数据库交换对此进行了测试,并且没有溢出。
如果您为每次登录使用 RoomDatabase
对象的新实例,请尝试在用户注销后关闭旧实例。 Room 通常会在不需要时关闭,但如果您需要立即关闭,最好手动关闭它。
roomDb.getOpenHelper().close();
我一直在努力让我的数据库备份正常工作,但我已经到了不知道该做什么的地步。
基本上,首先应用程序打开一个登录 activity,用户登录并从 Firebase 存储下载他们的数据库文件(如果存在),然后应用程序导航到 MainActivity。
在 MainActivity 中,我调用了一个将用户的数据库文件发送到 Firebase 存储的方法。我试图通过关闭数据库来管理该过程,但由于我无法修复错误“E/ROOM:无效跟踪器已初始化两次:/。”,然后我找到了使用检查点的答案(
(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 文件,而且我还获取了应用程序首次运行时创建的另一个数据库的数据,但该文件也未显示在数据库/文件夹中。
任何人都可以解释为什么文件夹没有显示应该存在的文件,应用程序从哪里获取被删除的数据以及如何修复它。
编辑:我的应用程序有多个 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;
}
如果您使用的是完全相同的 RoomDatabase
对象,只需在同一对象上构建另一个对象即可防止显示缓存数据。我已经使用大大小小的多个数据库交换对此进行了测试,并且没有溢出。
如果您为每次登录使用 RoomDatabase
对象的新实例,请尝试在用户注销后关闭旧实例。 Room 通常会在不需要时关闭,但如果您需要立即关闭,最好手动关闭它。
roomDb.getOpenHelper().close();