web-dev-qa-db-ja.com

Android部屋のデータベースはすべてのデータをエクスポートしません

Roomデータベースのバックアップ機能をセットアップしようとしています。問題は、ダウンロードしたSQLデータベースファイルにアプリ内の最新のデータセットが含まれていないことです。それは常にいくつかの最新の記録を見逃しています。部屋のデータベースをエクスポートする適切な方法はありますか? P.S. sqliteHelperを使用してデータベースを処理したときに同様の問題に直面しなかったので、Roomと関係があるに違いないと思います。

私のやり方:

@Throws(IOException::class)
private fun copyAppDbToDownloadFolder(address: String) {
    val backupDB = File(address, "studioDb.db") 
    val currentDB = applicationContext.getDatabasePath(StudioDatabase.DB_NAME)
    if (currentDB.exists()) {
        val src = FileInputStream(currentDB).channel
        val dst = FileOutputStream(backupDB).channel
        dst.transferFrom(src, 0, src.size())
        src.close()
        dst.close()
    }
}
8
Tuesday Four AM

私はそれを解決しました。 Roomで処理するSQLデータベースをエクスポート(保存)するときは、your_database.bdファイルとyour_database.walファイルの両方をエクスポート(および後でインポート)する必要があります。後でジャーナルであり、afaiuは最新の記録を保持します。

3
Tuesday Four AM

あなたは使用する必要があります

JournalMode.TRUNCATE

appDatabase.Javaで:

private static AppDatabase sInstance;

public static AppDatabase getDatabase(final Context context) {
    if (sInstance == null) {
        synchronized (AppDatabase.class) {
            if (sInstance == null) {
                sInstance = Room.databaseBuilder(context, AppDatabase.class, DATABASE_NAME)
                        .setJournalMode(JournalMode.TRUNCATE)
                        .build();
            }
        }
    }
    return sInstance;
}

このメソッドは、db.badおよびdb.walファイルを作成しません。ルームデータベースのエクスポートに支障をきたします。

DBファイルをエクスポートする場合:

リンク: 毎日フォルダを作成してdbをエクスポートする

10
Ali Azaz Alam

私も同じ問題を抱えていました。 wal(ログ先行書き込み)をコピーする必要はありません。これは一時ファイルです。 documentation によると、データベースをインポートまたはエクスポートする前に、データベースへのすべての接続を閉じる必要があります。これで問題が解決し、メインデータベースファイルのみをコピーする必要があります。

データベースクラスの例:

public abstract class AppDB extends RoomDatabase {    

    private static final Object sLock = new Object();

    private static AppDB INSTANCE;

    // create new database connection
    public static AppDB getInstance(final Context context) {
        synchronized (sLock) {
            if (INSTANCE == null) {
                INSTANCE = Room.databaseBuilder(context.getApplicationContext(), AppDB.class, "packagename")                    
                    .build();
                }
            return INSTANCE;
        }
    }

    // close database
    public static void destroyInstance(){
        if (INSTANCE.isOpen()) INSTANCE.close();
        INSTANCE = null;
    }
}
5