アプリケーションが始めて起動した直後に、データの事前取り込み(初期状態の設定)を必要とする場合があります。
事前取り込みの方法ついて、まとめました。
Room(Android Jetpack)でデータベースを構築した場合です。
※環境:Android Studio Ladybug | 2024.2.1 Patch 3
Kotlin 2.0.0
androidx.sqlite:sqlite:2.4.0
androidx.room:room-*:2.6.1
DB Browser for SQLite バージョン 3.13.1
※サンプルの全体像は「Roomでデータベースを構築」を参照
事前取り込みとは
「事前取り込み」とは、アプリケーションが始めて起動した直後の、データベースの初期状態を設定することです。
事前取り込みが必要かどうかはアプリケーションに依存します。ですので、事前取り込みはオプション的な実装です。
事前取り込みの実装
Roomは初期状態をファイルから取り込む機能を持っています。以下は、assetsフォルダから取り込む例です。

@Database(entities = arrayOf(Player::class), version = 1)
abstract class GameDb : RoomDatabase() {
abstract fun playerDao(): PlayerDao
companion object {
@Volatile
private var instance: GameDb? = null
fun getDatabase(context: Context): GameDb {
return instance ?: synchronized(this) {
val _instans = Room.databaseBuilder(
context,
GameDb::class.java,
"Game.db"
)
.createFromAsset("databases/Game.db") // 初期状態
.build()
instance = _instans
_instans
}
}
}
}
ただし、データベース識別子と初期状態は、スキーマが一致していなければなりません。
不一致の場合はエラーになり、アプリは起動しません。
事前データの作成
データベースの初期状態を「事前データ」といいます。
「ツール:DB Browser for SQLite」を用いた、事前データの作成方法を紹介します。
※DB Browser for SQLiteについては「データベースの閲覧」を参照
スキーマ情報のダンプ
事前データの作成で必要なスキーマ情報をダンプします。
build.gradle.ktsファイルにスキーマ情報のダンプ先フォルダを指定して下さい。
plugins { ... }
android {
namespace = "com.example.game"
compileSdk = 35
defaultConfig { ... }
buildTypes { ... }
compileOptions { ... }
kotlinOptions { ... }
buildFeatures { ... }
ksp {
arg("room.schemaLocation", "$projectDir/schemas")
}
}
dependencies { ... }
※「exportSchema = true」はスキーマのダンプを有効化するフラグです。デフォルトがtrueなので、指定の必要はありません。
@Database(entities = arrayOf(Player::class), version = 1, exportSchema = true)
abstract class GameDb : RoomDatabase() {
abstract fun playerDao(): PlayerDao // Daoの提供(必須)
companion object { ... }
}
アプリを実行すると、指定したフォルダにスキーム情報(jsonファイル)がダンプされます。実行の必要な点が難点です。

{
"formatVersion": 1,
"database": {
"version": 1,
"identityHash": "1389462589b209bcd420685744427f6a",
"entities": [
{
"tableName": "Player",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `score` INTEGER NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "score",
"columnName": "score",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '1389462589b209bcd420685744427f6a')"
]
}
}
スキーマ情報の「identityHashの値」は「entitiesの値」のハッシュ値です。Roomのシステムは、この値を用いてスキーマの一致を確認しています。
データベースの作成
SQLのコマンドファイル(GameDb.sql)を作成します。
スキーマ情報(jsonファイル)のハイライト部分を抜き出した物です。ただし、テーブル名(${TABLE_NAME})は置き換えて下さい。
CREATE TABLE IF NOT EXISTS `Player` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `score` INTEGER NOT NULL); CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT); INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '1389462589b209bcd420685744427f6a'); ※コマンドラインの終わりはセミコロン「;」です。
コマンドファイルをツールにインポートすれば、データベースが作成されます。

Rowデータの登録
必要なRowデータを登録して変更を書き込めば、事前データの作成完了です。

作成した事前データは、プロジェクトのassetsフォルダへ、コピー&ペーストして下さい。
事前取り込みの結果
アプリが始めて起動した直後に事前取り込みしたデータが表示されます。
関連記事:
