【问题标题】:How to add data to newly created Room database?如何将数据添加到新创建的 Room 数据库?
【发布时间】:2019-11-07 20:05:52
【问题描述】:

我尝试在 onCreate 方法中导入数据:

    db = Room.databaseBuilder(applicationContext,
            AppDatabase::class.java,
            "my-database")
        .allowMainThreadQueries()
        //.fallbackToDestructiveMigration()
        .addCallback(object: RoomDatabase.Callback() {
            override fun onCreate(db: SupportSQLiteDatabase) {
                Log.d("RoomDatabase.Callback", "onCreate called")
                importData()
            }
        })
        .build()

但这会导致

IllegalStateException: 递归调用 getDatabase

创建数据库后导入也不行:

    var performInitialImport = false

    db = Room.databaseBuilder(applicationContext,
            AppDatabase::class.java,
            "my-database")
        .allowMainThreadQueries()
        //.fallbackToDestructiveMigration()
        .addCallback(object: RoomDatabase.Callback() {
            override fun onCreate(db: SupportSQLiteDatabase) {
                Log.d("RoomDatabase.Callback", "onCreate called")
                performInitialImport = true
            }
        })
        .build()

    Log.d("PerformInitialImport", "$performInitialImport")

    if (performInitialImport) {
        importData()
    }

因为在数据库建立后控制流继续之前回调没有被执行。

D/PerformInitialImport: 假

来之前

D/RoomDatabase.Callback: onCreate 调用

在应用程序的运行日志中。

我迷路了。第一次创建时如何将数据导入数据库?

更新:importData 方法使用在第一行创建的AppDatabase 实例。传递给onCreatedb 参数是底层的低级数据库。自然,我想使用 DAO 和我已经拥有的实体来填充数据库......

【问题讨论】:

  • 最好在后台服务中检查一些条件以进行导入。例如if (dao.count() == 0) importData() 之类的东西。这是因为数据的导入可能需要很长时间,所以最好异步进行。

标签: android android-room


【解决方案1】:

你得到这个行为的原因是构建没有打开数据库,直到你使用数据库才打开它,然后如果数据库不存在,它将被创建并调用 onCreate .

因此 performInitialImport 将始终为 false,除非您访问数据库,强制打开它。

在进行测试之前,您需要打开(访问)数据库。

示例:-

class MainActivity : AppCompatActivity() {

    var firstrun = false
    var myTableDao :MyTableDao? = null


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        Log.d("ROOMBUILD","Building Room Database")
        val db = Room.databaseBuilder(this,AppDatabase::class.java,"mydb")
            .allowMainThreadQueries()
            .addCallback(object: RoomDatabase.Callback()
            {
                override fun onCreate(db: SupportSQLiteDatabase) {
                    Log.d("ONCREATE","onCreate called.")
                    super.onCreate(db)
                    firstrun = true;
                }
            }
            )
            .build()
        Log.d("ROOMBUILD","Room database built")
        myTableDao = db!!.myTableDao()
        //myTableDao!!.getAll() //would also work assuming getAll is defined in the Dao
        db.openHelper.writableDatabase //<<<<<<<<<< Force open
        if (firstrun) {
            importData()
        }
         for (m in myTableDao!!.getAll()) {
             Log.d("MYTABLEINFO","Names is " + m.name + " ID is " + m.id)
         }
    }

    fun importData() {
        Log.d("IMPORTING","Data being imported")
        var mytable = MyTable()
        mytable.name = "MyData"
        myTableDao?.insert(mytable)
    }
}

结果

安装时:-

2019-11-08 10:36:18.629 D/ROOMBUILD: Building Room Database
2019-11-08 10:36:18.642 D/ROOMBUILD: Room database built
2019-11-08 10:36:18.664 D/ONCREATE: onCreate called.
2019-11-08 10:36:18.669 D/IMPORTING: Data being imported
2019-11-08 10:36:18.675 D/MYTABLEINFO: Names is MyData ID is 1

后续运行:-

2019-11-08 10:37:07.759 D/ROOMBUILD: Building Room Database
2019-11-08 10:37:07.772 D/ROOMBUILD: Room database built
2019-11-08 10:37:07.789 D/MYTABLEINFO: Names is MyData ID is 1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-26
    相关资源
    最近更新 更多