web-dev-qa-db-ja.com

ルームデータベースはOnCreateコールバックを強制します

データを事前に入力する必要があるRoomDatabaseを使用してアプリケーションを開発しています。私はすでにonCreate()コールバックを追加することでそれを行うことができましたが、データベースに初めてアクセスしたときにのみ呼び出されます(Daos関数の1つを呼び出すように)。

読み取りまたは書き込み操作を行わずにデータベースを強制的に作成する方法はありますか?

それは私のコードです、MyDatabase.get()App.onCreate()で呼び出されます

@Database(entities = {Entity1.class, Entity2.class}, version = 1, exportSchema = true)
public abstract class MyDatabase extends RoomDatabase {

    private static MyDatabase sInstance;

    public synchronized static TaxCodeDatabase get(Context context) {
        if (sInstance == null) {
            sInstance = buildDatabase(context);
        }
        return sInstance;
    }

    private static MyCodeDatabase buildDatabase(final Context context) {
        return Room.databaseBuilder(context,
                MyCodeDatabase.class,
                "my-database")
                .addCallback(new Callback() {
                    @Override
                    public void onCreate(@NonNull SupportSQLiteDatabase db) {
                        super.onCreate(db);
                        sInstance.preFillData(context);
                      });
                    }
                })
                .build();
    }

    public abstract Entity1Dao entity2Dao();

    public abstract Entity2Dao entity1Dao();

    /**
     * Populates the database with a series of initial data
     *
     * @param aContext
     */
    public void prePopulateData(Context aContext) {
        //Populate database here
    }
12
Jameido

読み取りまたは書き込み操作を行わずにデータベースを強制的に作成する方法はありますか?

いいえ、ごめんなさい。

ただし、Roomを呼び出す前に、事前入力されたデータベースを所定の位置にコピーすることを妨げるものは何もありません。事前入力されたデータベースにRoomのメタデータが含まれていることを確認する必要があります(たとえば、Room自体を使用してデータベースを作成するなど)。

4
CommonsWare

データベースビルダーで.build()を呼び出した後、Roomデータベースに初期データが入力されない理由を理解するのにしばらく時間がかかりました。

私の場合、移行とコールバックが実際の読み取り/書き込み操作でのみトリガーされるのは、直感に反しています。実際には、Roomが_class RoomOpenHelper_を使用する理由によって引き起こされる問題であり、ドキュメントに記載されているとおりです。

データベースが開かれるまで構成への参照を保持するオープンヘルパー。

その結果、SqliteのRoomOpenHelperが実際にはデータベースの移行を実行し、作成されずに(Javaでの遅延クラスの読み込み)、SQLiteOpenHelperクラスのインスタンスに格納された構成とすべてのコールバック。

この動作を克服するには、getWritableDatabase()を引き起こすすべての操作を実行する必要があります。私は次のアプローチで終わりました:

_RoomDatabase db = Room.databaseBuilder(context,
            ...)
            .build();

  // and then
db.beginTransaction()
db.endTransaction()

  // or query a dummy select statement
db.query("select 1", null)

return db
_

その後、データベースが作成され、初期データが入力されます。

13
Maxim

デバイスファイルエクスプローラーを開き、/ data/data/Your appに移動して、データベースフォルダーを削除します。

0
Jeffrey