Si vous souhaitez que votre application démarre avec une base de données déjà chargée avec un ensemble spécifique de données, vous pouvez préremplir la base de données. Dans Room, vous pouvez utiliser des API pour préremplir une base de données lors de l'initialisation avec le contenu d'un fichier de base de données préinstallé sur le système de fichiers de l'appareil.
Préremplir à partir d'un composant d'application
Pour préremplir une base de données Room à partir d'un fichier de base de données préinstallé situé
n'importe où dans le répertoire assets/ de votre application, appelez la fonction createFromAsset
à partir de votre objet RoomDatabase.Builder avant d'appeler build :
Room.databaseBuilder<AppDatabase>(appContext, "sample.db") .createFromAsset("database/myapp.db") .build()
La fonction createFromAsset accepte un argument de chaîne qui contient un chemin d'accès relatif du répertoire assets/ vers le fichier de base de données préinstallé.
Préremplir à partir du système de fichiers
Pour préremplir une base de données Room à partir d'un fichier de base de données préinstallé et situé
n'importe où dans le système de fichiers de l'appareil, à l'exception du répertoire assets/ de votre application,
appelez la fonction createFromFile à partir de votre objet RoomDatabase.Builder
avant d'appeler build :
Room.databaseBuilder<AppDatabase>(appContext, "sample.db") .createFromFile(File("mypath")) .build()
La fonction createFromFile accepte un File argument pour le
fichier de base de données préinstallé. Room crée une copie du fichier désigné au lieu de l'ouvrir directement. Assurez-vous donc que votre application dispose des autorisations de lecture sur le fichier.
Gérer les migrations qui incluent des bases de données préinstallées
Les fichiers de base de données préinstallés peuvent également modifier la façon dont votre base de données Room gère les migrations de remplacement. En règle générale, lorsque les migrations destructives sont activées et que Room doit effectuer une migration sans chemin de migration, il supprime toutes les tables de la base de données et crée une base de données vide avec le schéma spécifié pour la version cible. Toutefois, si vous incluez un fichier de base de données préinstallé avec le même numéro que la version cible, Room remplit le contenu de la nouvelle base de données avec le contenu de ce fichier après avoir effectué la migration destructive.
Pour en savoir plus sur la migration des bases de données Room, consultez la page Migrer votre base de données Room.
Les sections suivantes présentent quelques exemples concrets de fonctionnement.
Exemple : migration de remplacement avec une base de données préinstallée
Supposons que :
- Votre application définit une base de données Room sur la version 3.
- L'instance de base de données déjà installée sur l'appareil utilise la version 2.
- Il existe un fichier de base de données préinstallé dans la version 3.
- Aucun chemin de migration de la version 2 vers la version 3 n'a été implémenté.
- Les migrations destructives sont activées.
// Database class definition declaring version 3. @Database(entities = [SampleEntity::class], version = 3) abstract class FallbackAppDatabase : RoomDatabase() { // ... } fun createFallbackDb(appContext: Context) { Room.databaseBuilder<FallbackAppDatabase>(appContext, "sample.db") .createFromAsset("database/myapp.db") .fallbackToDestructiveMigration() .build() }
Voici ce qui se passe dans ce cas :
- Étant donné que la base de données définie dans votre application est sur la version 3 et que l'instance de base de données déjà installée sur l'appareil est sur la version 2, une migration est nécessaire.
- Comme aucun plan de migration n'a été implémenté entre la version 2 et la version 3, il s'agit d'une migration de remplacement.
- Comme vous appelez la fonction de compilation
fallbackToDestructiveMigrationbuilder, la migration de remplacement est destructrice. Room supprime l'instance de base de données installée sur l'appareil. - Étant donné qu'il existe un fichier de base de données préinstallé dans la version 3, Room recrée la base de données et l'insère à l'aide du contenu de ce fichier. Si votre fichier de base de données préinstallé est dans la version 2, Room détermine qu'il ne correspond pas à la version cible et ne l'utilise donc pas pour la migration de remplacement.
Exemple : implémentation d'une migration avec une base de données préinstallée
Supposons à la place que votre application implémente un chemin de migration de la version 2 vers la version 3 :
// Database class definition declaring version 3. @Database(entities = [SampleEntity::class], version = 3) abstract class ImplementedAppDatabase : RoomDatabase() { // ... } // Migration path definition from version 2 to version 3. val MIGRATION_2_3 = object : Migration(2, 3) { override suspend fun migrate(connection: SQLiteConnection) { // ... } } fun createImplementedDb(appContext: Context) { Room.databaseBuilder<ImplementedAppDatabase>(appContext, "sample.db") .createFromAsset("database/myapp.db") .addMigrations(MIGRATION_2_3) .build() }
Voici ce qui se passe dans ce cas :
- Étant donné que la base de données définie dans votre application est sur la version 3 et que la base de données déjà installée sur l'appareil est sur la version 2, une migration est nécessaire.
- Étant donné qu'un chemin de migration a été implémenté entre la version 2 et la version 3,
Room exécute la fonction
migratedéfinie pour mettre à jour l'instance de base de données de l'appareil vers la version 3, ce qui préserve les données qui se trouvent déjà dans la base de données. Room n'utilise pas le fichier de base de données préinstallé, car il n'utilise ce type de fichiers que pour une migration de remplacement.
Exemple : migration en plusieurs étapes avec une base de données préinstallée
Les fichiers de base de données préinstallés peuvent également affecter les migrations constituées de plusieurs étapes. Prenons le cas suivant :
- Votre application définit une base de données Room dans la version 4.
- L'instance de base de données déjà installée sur l'appareil utilise la version 2.
- Il existe un fichier de base de données préinstallé dans la version 3.
- Un chemin de migration a été implémenté de la version 3 à la version 4, mais pas de la version 2 à la version 3.
- Les migrations destructives sont activées.
// Database class definition declaring version 4. @Database(entities = [SampleEntity::class], version = 4) abstract class MultiStepAppDatabase : RoomDatabase() { // ... } val MIGRATION_3_4 = object : Migration(3, 4) { override suspend fun migrate(connection: SQLiteConnection) { // ... } } fun createMultiStepDb(appContext: Context) { Room.databaseBuilder<MultiStepAppDatabase>(appContext, "sample.db") .createFromAsset("database/myapp.db") .addMigrations(MIGRATION_3_4) .fallbackToDestructiveMigration() .build() }
Voici ce qui se passe dans ce cas :
- Étant donné que la base de données définie dans votre application est sur la version 4 et que l'instance de base de données déjà installée sur l'appareil est sur la version 2, une migration est nécessaire.
- Comme aucun chemin de migration n'a été implémenté entre la version 2 et la version 3, il s'agit d'une migration de remplacement.
- Comme vous appelez la fonction de compilation
fallbackToDestructiveMigrationbuilder, la migration de remplacement est destructrice. Room supprime l'instance de base de données sur l'appareil. - Étant donné qu'il existe un fichier de base de données préinstallé dans la version 3, Room recrée la base de données et l'insère à l'aide du contenu de ce fichier.
- La base de données installée sur l'appareil utilise désormais la version 3. Comme elle est encore inférieure à la version définie dans votre application, une autre migration est nécessaire.
- Étant donné qu'un chemin de migration a été implémenté entre la version 3 et la version 4,
Room exécute la fonction
migratedéfinie pour mettre à jour l'instance de base de données de l'appareil vers la version 4, ce qui préserve les données qui ont été copiées à partir du fichier de base de données préinstallé de la version 3.