Room Database强制OnCreate回调

时间:2018-01-16 12:09:47

标签: java android android-room

我正在使用RoomDatabase开发一个需要预先填充其数据的应用程序;我已经设法通过添加onCreate()回调来实现它,但只有在第一次访问数据库时才会调用它(就像调用其中一个Daos函数一样)。

有没有办法在不进行任何读写操作的情况下强制创建数据库?

我的代码MyDatabase.get()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
    }

4 个答案:

答案 0 :(得分:8)

花了一段时间我才理解为什么在数据库构建器上调用.build()后,为什么Room数据库没有填充初始数据。

对于我来说,迁移和回调仅在真正的读/写操作时才触发是真的违反直觉的。实际上是由于Room使用class RoomOpenHelper的原因引起的,正如文档中所述:

  

一个开放式助手,在打开数据库之前,该助手会保留对配置的引用。

结果是,配置和所有回调都存储在RoomOpenHelper类的实例中,而Sqlite的SQLiteOpenHelper(实际上执行数据库迁移)没有创建(Java中的惰性类加载)。

要解决此问题,应执行任何导致getWritableDatabase()的操作。我最终采用了以下方法:

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

此后,将创建数据库并使用初始数据填充

答案 1 :(得分:3)

  

有没有办法在不进行任何读写操作的情况下强制创建数据库?

不,抱歉。

但是,在调用Room之前,没有什么可以阻止您将预先填充的数据库复制到位置。您需要确保预先填充的数据库中包含Room的元数据(例如,通过使用Room本身创建该数据库)。

答案 2 :(得分:1)

Room version 2.2.0 (October 2019)引入了用于数据库的预填充的内置方法:

  1. 应从预打包的数据库文件(* .db)中放入assets/目录中。
  2. 应该从预打包的数据库文件(* .db)中将assets/目录之外的其他位置放置。

有关更多详细信息,您可以阅读official documentation

要获取答案-如何准备预打包的数据库,请阅读this article in SO

答案 3 :(得分:0)

打开设备文件浏览器并导航到 / data / data / 您的应用,然后删除数据库文件夹。