将数据从适配器类插入房间数据库会导致应用程序崩溃



因此,当发生onclicklistener事件时,我一直在尝试从适配器类向房间数据库插入数据。但每次我这样做时,我的应用程序都会崩溃,日志中没有任何错误消息。事件中唯一发生的事情是创建数据库实例,一旦创建,应用程序就会崩溃。

我的物品类别:


@Entity(tableName="item")
data class Item(
@PrimaryKey(autoGenerate = true)
val id: Int = 0,
@ColumnInfo(name = "path")
val path: String,
@ColumnInfo(name = "name")
val itemName: String,
)

我的DAO:

@Dao
interface ItemDao {
@Insert(onConflict = OnConflictStrategy.IGNORE)
//suspend is not needed in newer versions of kotlin
fun insert(item: Item)
}

我的ItemRoomDatabase.kt:

@Database(entities = [Item::class], version = 1, exportSchema = false)
abstract class ItemRoomDatabase : RoomDatabase() {
abstract fun itemDao(): ItemDao
companion object {
@Volatile
private var INSTANCE: ItemRoomDatabase? = null
fun getDatabase(context: Context): ItemRoomDatabase {
return INSTANCE ?: synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
ItemRoomDatabase::class.java,
"item_database"
)
.fallbackToDestructiveMigration()
.build()
INSTANCE = instance
return instance
}
}
}
}

我的Starred应用程序代码:

class StarredApplication : Application() {
val database: ItemRoomDatabase by lazy { ItemRoomDatabase.getDatabase(this) }
}

这是我的InventoryViewModel.kt:

class InventoryViewModel(private val itemDao: ItemDao) : ViewModel()  {
private fun insertItem(item: Item) {
viewModelScope.launch {
itemDao.insert(item)
}
}

fun isEntryValid(path: String, name: String): Boolean {
if (path.isBlank() || name.isBlank()) {
return false
}
return true
}
private fun getNewItemEntry(path: String, name: String): Item {
return Item(
path = path,
itemName = name,
)
}
fun addNewItem(path: String, name: String) {
val newItem = getNewItemEntry(path, name)
insertItem(newItem)
}
}
class InventoryViewModelFactory(private val itemDao: ItemDao) : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(InventoryViewModel::class.java)) {
@Suppress("UNCHECKED_CAST")
return InventoryViewModel(itemDao) as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
}

因此,在我的片段(PdfContainerFragment.kt(中,我创建了库存视图模型的viewModel实例,并将其传递给适配器类。

private val viewModel: InventoryViewModel by activityViewModels {
InventoryViewModelFactory(
(activity?.application as StarredApplication).database.itemDao()
)
}

因此,在我的适配器类中,我试图将数据插入房间数据库,但我一点击事件,应用程序就会崩溃。

//BindViewHolder 内部

holder.star.setOnClickListener{
with(model){
setPath(paths)
}
var pdfName = holder.textView.text.toString()
Log.d("PathPdfContainerAdapter", paths)
Log.d("pdfNamePdfAdapter", pdfName)
addNewItem( paths, pdfName)
holder.star.setImageResource(R.drawable.ic_star_fill)
}
// Outside onViewBinding
private fun isEntryValid(path: String, pdfName: String): Boolean {
return roomViewModel.isEntryValid(
path,
pdfName,
)
}
private fun addNewItem( path: String, name: String) {
if(isEntryValid(path, name)) {
roomViewModel.addNewItem(
path,
name,
)
}
}

我是应用程序开发的新手,所以请安静下来让我理解。

所以发生的事情是,我的应用程序在logcat上没有任何消息的情况下崩溃了,所以我尝试使用调试器,发现异常

Cannot access database on the main thread since it may potentially lock the UI for a long period of time.

因此,在构建数据库时,我将数据库生成器应用于allowMainThreadQueries。这不是一个完美的解决方案,但目前有效。


@Database(entities = [Item::class], version = 1, exportSchema = false)
abstract class ItemRoomDatabase : RoomDatabase() {
abstract fun itemDao(): ItemDao
companion object {
@Volatile
private var INSTANCE: ItemRoomDatabase? = null
fun getDatabase(context: Context): ItemRoomDatabase {
return INSTANCE ?: synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
ItemRoomDatabase::class.java,
"item_database"
)
.fallbackToDestructiveMigration()
.allowMainThreadQueries()
.build()
INSTANCE = instance
return instance
}
}
}
}

最新更新