web-dev-qa-db-fra.com

Comment remplir la table de base de données Android Room lors de la première exécution?

Dans SQLiteOpenHelper, il existe une méthode onCreate(SQLiteDatabase ...) que j’ai utilisée pour renseigner les tables de base de données avec certaines données initiales.

Est-il possible d'insérer des données dans la table de la base de données Room le premier App Run?

17
user2538289

Vous pouvez exécuter des scripts après la création de la base de données ou à chaque ouverture de la base de données à l'aide de RoomDatabase.Callback, cette classe est disponible dans la dernière version de la bibliothèque de salle.

Vous devez implémenter les méthodes onCreate et onOpen de RoomDatabase.Callback et les ajouter à RoomDatabase.Builder comme indiqué ci-dessous.

yourDatabase = Room.databaseBuilder(context, YourDatabase.class, "your db")
    .addCallback(rdc)
    .build();

RoomDatabase.Callback rdc = new RoomDatabase.Callback() {
    public void onCreate (SupportSQLiteDatabase db) {
        // do something after database has been created
    }
    public void onOpen (SupportSQLiteDatabase db) {
        // do something every time database is open
    }
};

Référence

Vous pouvez utiliser Room DAO lui-même dans les méthodes RoomDatabase.Callback pour remplir la base de données. Pour des exemples complets, voir Exemple de pagination et de salle

   RoomDatabase.Callback dbCallback = new RoomDatabase.Callback() {
        public void onCreate(SupportSQLiteDatabase db) {
            Executors.newSingleThreadScheduledExecutor().execute(new Runnable() {
                @Override
                public void run() {
                   getYourDB(ctx).yourDAO().insertData(yourDataList);
                }
            });
        }
    };
61
Arnav Rao

J'ai essayé d'utiliser RoomDatabase.Callback comme suggéré par Arnav Rao, mais pour utiliser un rappel, vous ne pouvez pas utiliser DAO car le rappel est créé avant la construction de la base de données. Vous pouvez utiliser db.insert et les valeurs de contenu, mais je ne pensais pas que cela aurait été correct. Donc, après avoir examiné un peu plus - cela m’a pris bien des années - mais j’ai trouvé la réponse lorsque j’ai parcouru les échantillons fournis par Google.

https://github.com/googlesamples/Android-architecture-components/blob/master/PersistenceContentProviderSample/app/src/main/Java/com/example/Android/contentprovidersample/data/SampleDatabase.Java

Voir la ligne 52 et la méthode à la ligne 71 - Dans celle-ci, vous pouvez voir qu'après la construction de l'instance de base de données, la ligne suivante appelle une méthode qui vérifie s'il existe des enregistrements dans la base de données (à l'aide de la DAO), puis si elle est vide. insère les données initiales (encore une fois en utilisant le DAO).

J'espère que cela aide quelqu'un d'autre qui était coincé :)

5
N1234

J'ai essayé un certain nombre de façons de le faire, chacune étant non disponible.

Tout d'abord, j'ai essayé d'ajouter une implémentation de migration à Room en utilisant la méthode 'addMigrations', mais j'ai constaté qu'elle ne s'exécutait que lors d'une mise à niveau de la base de données, mais pas lors de sa création.

Ensuite, j'ai essayé de passer une implémentation SQLiteOpenHelper à Room en utilisant la méthode 'openHelperFactory'. Mais après avoir créé un groupe de classes afin de contourner les modificateurs d'accès au niveau du paquet de Room, j'ai abandonné l'effort. J'ai aussi essayé de sous-classer FrameworkSQLiteOpenHelperFactory de Room, mais encore une fois, le modificateur d'accès au niveau du paquet de son constructeur ne le supportait pas.

Enfin, j'ai créé un service IntentService pour renseigner les données et les ai appelées à partir de la méthode onCreate de ma sous-classe Application. L’approche fonctionne mais une solution plus efficace devrait être le prochain correctif du problème de suivi évoqué par Sinigami ailleurs sur cette page. 

Darryl

[Ajouté le 19 juillet 2017]

Le problème semble résolu dans la salle 1.0.0. Alpha 5. Cette version a ajouté un rappel à RoomDatabase qui vous permet d'exécuter du code lors de la création de la base de données. Jeter un coup d'œil à:

https://developer.Android.com/reference/Android/Arch/persistence/room/RoomDatabase.Callback.html

5
Darryl Staflund
@Provides
@Singleton
LocalDatabase provideLocalDatabase(@DatabaseInfo String dbName, Context context) {
    return Room.databaseBuilder(context, LocalDatabase.class, dbName)
            .addCallback(new RoomDatabase.Callback() {
                @Override
                public void onCreate(@NonNull SupportSQLiteDatabase db) {
                    super.onCreate(db);
                    db.execSQL("INSERT INTO id_generator VALUES(1, 1, 1);");
                }
            })
//                .addMigrations(LocalDatabase.MIGRATION_1_2)
            .build();
}
1
nAkhmedov