我一直在努力讓我的資料庫備份作業,但我已經到了不知道該怎么做的地步。
基本上,首先應用程式打開一個登錄活動,用戶登錄并從 Firebase 存盤下載他們的資料庫檔案(如果存在),然后應用程式導航到 MainActivity。
在 MainActivity 中,我呼叫了一個將用戶的資料庫檔案發送到 Firebase Storage 的方法。我試圖通過關閉資料庫來管理該程序,但由于我無法修復“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 檔案,而且我還獲取了應用程式首次運行時創建的另一個資料庫的資料,但該檔案也未顯示在 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;
}
uj5u.com熱心網友回復:
如果您使用完全相同的RoomDatabase物件,只需在同一個物件上構建另一個物件即可防止對快取資料的任何保留顯示。我已經使用多個大大小小的資料庫交換對此進行了測驗,并且沒有溢位。
如果RoomDatabase每次登錄都使用物件的新實體,請嘗試在用戶注銷后關閉舊實體。Room 通常會在不需要時關閉,但如果您需要立即關閉,手動關閉它是您最好的選擇。
roomDb.getOpenHelper().close();
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/375475.html
標籤:爪哇 安卓 数据库 sqlite android-room
下一篇:Flutter中的多對多關系
