【Android開発】Roomを使う際にデータをあらかじめ設定(Prepopulate)する方法

目次

  1. 背景
  2. Roomを利用したDBの作成
  3. asset フォルダの作成
  4. DBファイルをデバイスから取得する
  5. DBにデータを格納
  6. DBファイルの配置
  7. バージョンを更新してDBを初期化する
  8. まとめ
  9. 関連記事

背景

こんにちは。 karintomania(@karintozuki)です。

Androidアプリを開発していると、
DBにあらかじめデータをセットしておきたいケースが多いと思う。

少し調べると、Prepopulateというキーワードで説明が公式にも載っている。
https://developer.android.com/training/data-storage/room/prepopulate

このページ曰く、

asset/ フォルダにDBファイルを置いて以下のコードを実行すればOK (意訳)

AppDatabase.kt
1
2
3
Room.databaseBuilder(appContext, AppDatabase.class, "Sample.db")
.createFromAsset("database/myapp.db")
.build()

ふむふむ、、、わからん。

このままではいかんせん、手の動かしようがない。

  • assetフォルダってどこよ?
  • myapp.dbはどうやって作るの?
  • どうやって初期データを用意するの?

これらをどうにか解決したので、メモを残しておきたい。

Roomを利用したDBの作成

ここは普通にいろんなサイトで紹介されているので、
割愛するが、一点だけ注意。

versionを2以上にしとかないと後々めんどい。
理由は後述。

versionの設定
1
2
3
4
@Database(entities = arrayOf(User::class), version = 2) // versionを2以上にする
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
}

また、冒頭で登場した呪文をDatabaseBuilderでDBを宣言している箇所に記載する。

AppDatabase.kt
1
2
3
Room.databaseBuilder(appContext, AppDatabase.class, "Sample.db")
.createFromAsset("database/myapp.db") // この一行を追加
.build()

asset フォルダの作成

まずデータを入れたDBファイルを格納するための、
assetフォルダを作成する。

プロジェクトフォルダを右クリックして、
New > Folder > Asset Folder

次のダイアログは特にこだわりがなければデフォルトでFinishボタンを押すだけ。

これでassetフォルダがプロジェクト内に作成される。

DBファイルをデバイスから取得する

Roomで作成されたDBファイルを取得するため、Device File Explorerを開く。

各アプリのDBファイルは以下のパスに存在する。
/data/data/(アプリのパッケージ名)/databases/(DB名)

これを右クリック > Save asして、ローカルPCの適当なフォルダに保存する

DBにデータを格納

先ほど保存したDBファイルにデータを流し込む。
このファイルはSQLiteなので、SQLクライアントを使うなり何なりでデータを入れることが可能。

ちなみに、私はDBevaerを利用した。
Macの無料SQLクライアントDBeaverを紹介する

DBファイルの配置

作成したDBファイルをassetフォルダに格納する。
これは普通にコピー&ペーストすればOK。

バージョンを更新してDBを初期化する

DBの初期化は、DBクラス内に記載されているバージョンが更新されたタイミングで行われる。

  • assetに入れたDBのバージョン
  • DBクラスのバージョン
    現状、二つのバージョンは同じなので、バージョンを更新してあげないといけない。

またややこしいのが、データが適用されるのは、
asset内のDBのバージョン > DBクラスのバージョン
の状態から
asset内のDBのバージョン <= DBクラスのバージョン
になった時のみらしい。

なので、とても面倒だが、
DBクラスのバージョンを下げる(例えばv1)→Build→元に戻す(2に戻す)
といったプロセスを踏ませることで初期化が行われる。

バージョンが1の場合、
asset内のDBのバージョン > DBクラスのバージョン
となる状態を作れないために、最初にバージョンを2にする作業が必要だったのだ。

まとめ

お疲れ様でした。
私はこの方法にたどり着くまで一週間くらいかかってしまった。

にしてもスマートじゃないところがたくさんあるので、
もっと良い方法があれば教えてください。

それじゃ今日はこの辺で。

関連記事

こちらの記事もおすすめ。
SQLiteとは?特徴と使い方を解説する