如何在房间数据库中预填充数据

Posted

技术标签:

【中文标题】如何在房间数据库中预填充数据【英文标题】:How to pre-populate data in Room Database 【发布时间】:2020-04-12 07:55:08 【问题描述】:

我正在通过 Java 教程开发联系人应用程序。我能够将转换转换为 Kotlin,直到我开始遇到 AsyncTask 预填充数据的问题。

我确认我可以将活动中的数据发送到 Room 数据库,但似乎没有来自预填充数据。

数据库

@Database(entities = [ContactEntity::class], version = 1, exportSchema = false)
abstract class ContactDatabase : RoomDatabase() 

    abstract fun getContactDao():ContactDao

    companion object
        private var instance:ContactDatabase?=null

        @kotlin.UseExperimental(InternalCoroutinesApi::class)
        fun getInstance(context: Context): ContactDatabase 

            return instance?: synchronized(this)
                instance?: Room.databaseBuilder(context.applicationContext,
                    ContactDatabase::class.java, "contact_database")
                    .fallbackToDestructiveMigration()
                    .addCallback(roomCallBack)
                    .build()
            
        

        val roomCallBack = object: RoomDatabase.Callback()
            override fun onCreate(db: SupportSQLiteDatabase) 
                super.onCreate(db)
                instance?.let  PopulateDbAsyncTask(it).execute() 
            

        

        internal class PopulateDbAsyncTask(db: ContactDatabase) : AsyncTask<Void, Void, Void>()

            val contactDao = db.getContactDao()
            override fun doInBackground(vararg p0: Void?): Void? 
                contactDao.insert(ContactEntity("Darot", "Tosin", "M", "Atlantic View", "08060085192", R.drawable.maleavatar))
                contactDao.insert(ContactEntity("Tola", "Folawo", "M", "Atlantic View", "08060085192", R.drawable.femaleavatar))
                contactDao.insert(ContactEntity("Aisha", "Monday", "M", "Atlantic View", "08060085192", R.drawable.femaleavatar))
                return null
            
        
    

MainActivity

class MainActivity : AppCompatActivity() 


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

//        val contacts:ArrayList<ContactEntity>

        val contacts = arrayOf(

            ContactEntity("Tola", "Folawo", "M", "Atlantic View", "08060085192", R.drawable.femaleavatar),
            ContactEntity("Aisha", "Monday", "M", "Atlantic View", "08060085192", R.drawable.femaleavatar),
            ContactEntity("Darot", "Tosin", "M", "Atlantic View", "08060085192", R.drawable.maleavatar)
        )

        val arrayList: ArrayList<String> = ArrayList<String>(5)
        var list: MutableList<ContactEntity> = mutableListOf<ContactEntity>()

        list.add(ContactEntity("Tola", "Folawo", "M", "Atlantic View", "08060085192", R.drawable.femaleavatar))
        list.add(ContactEntity("Aisha", "Monday", "M", "Atlantic View", "08060085192", R.drawable.femaleavatar))
        list.add(ContactEntity("Darot", "Tosin", "M", "Atlantic View", "08060085192", R.drawable.maleavatar))

        val contactList = ArrayList<ContactEntity>()

        contactList.addAll(list)


        recyclerView.layoutManager = LinearLayoutManager(this)
        recyclerView.setHasFixedSize(true)
        val adapter = ContactAdapter()
        recyclerView.adapter = adapter


        val contactViewModel = ViewModelProviders.of(this).get(ContactViewModel::class.java)
        contactViewModel.getAllContactsModel().observe(this, object:Observer<List<ContactEntity>>
            override fun onChanged(t: List<ContactEntity>) 
                adapter.setContacts(t)
                Toast.makeText(applicationContext, "$t", Toast.LENGTH_LONG).show()
            
        )
    

通过上面的代码,我可以手动将数据填充到数据库中。我哪里做错了?

【问题讨论】:

只是为了澄清一下,当您将联系人从主要活动添加到数据库时,它会起作用。但是,当您尝试使用 ContactDatabase 中的 AsyncTask 添加联系人时,它什么也不做?是否有任何错误被抛出? 是但没有错误。我认为 roomcallback 不起作用。 尝试删除本地应用存储(cnet.com/how-to/…) 或删除应用然后再次尝试运行应用 我这样做了,但还是一样 【参考方案1】:

除非表被读取或写入,否则不会触发房间回调。所以做“.build”从来没有真正击中回调。因此,一个简单的解决方案是在构建表后直接开始和结束事务。

db.beginTransaction()
db.endTransaction()

这里是一个类似 Stack Overflow 问题的链接,可以帮助您:Room Database force OnCreate callback

【讨论】:

以上是关于如何在房间数据库中预填充数据的主要内容,如果未能解决你的问题,请参考以下文章

如何使用链接从数据库中预填充表单字段?

如何根据先前的用户选择在 Django 中预填充(多个)ChoiceField

如何防止表单元素在 Chrome 中预填充

如何在 jsf 中预填充 h:inputText

initialValues仅在硬编码时预填充数据,但不在动态数据中预填充数据

使用来自 SQLAlchemy 对象的数据在烧瓶中预填充 WTforms