Estoy desarrollando una aplicación con RoomDatabase que necesita rellenar previamente sus datos; Ya logré hacerlo agregando la devolución de llamada onCreate()
, pero solo se llama cuando se accede a la base de datos la primera vez (como llamar a una de las funciones de Daos).
¿Hay alguna forma de forzar la creación de la base de datos sin realizar ninguna operación de lectura o escritura?
Ese es mi código, MyDatabase.get()
se llama en 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
}
3 respuestas
¿Hay alguna forma de forzar la creación de la base de datos sin realizar ninguna operación de lectura o escritura?
No lo siento.
Sin embargo, no hay nada que le impida copiar la base de datos rellenada previamente antes de invocar Room. Debería asegurarse de que la base de datos rellenada previamente contenga los metadatos de Room (por ejemplo, creando esa base de datos utilizando Room).
Me tomó un tiempo entender por qué una base de datos de Room no se llena con datos iniciales después de invocar .build()
en un generador de bases de datos.
En cuanto a mí, es realmente contra-intuitivo que las migraciones y las devoluciones de llamada se desencadenan solo en una operación de lectura / escritura real. En realidad, el problema se debe a que Room utiliza class RoomOpenHelper
que, como se menciona en la documentación:
Un asistente abierto que contiene una referencia a la configuración hasta que se abre la base de datos.
Como resultado, la configuración y todas las devoluciones de llamada almacenadas en la instancia de la clase RoomOpenHelper
mientras que la Sqlite SQLiteOpenHelper
, que realmente realiza migraciones de la base de datos, no se crea (carga de clase diferida en Java).
Para superar este comportamiento, se debe realizar cualquier operación que cause getWritableDatabase()
. Terminé con el siguiente enfoque:
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
Después de eso, la base de datos se creará y se completará con los datos iniciales.
Abra el explorador de archivos del dispositivo y navegue hasta / data / data / Su aplicación y elimine la carpeta de bases de datos.
Preguntas relacionadas
Nuevas preguntas
java
Java es un lenguaje de programación de alto nivel. Utilice esta etiqueta cuando tenga problemas para usar o comprender el idioma en sí. Esta etiqueta rara vez se usa sola y se usa con mayor frecuencia junto con [spring], [spring-boot], [jakarta-ee], [android], [javafx], [hadoop], [gradle] y [maven].