我正在尝试使用带有暂停关键字的房间数据库。
我可以成功地将数据插入数据库。但是在那之后,insert 方法将不会返回任何内容,这意味着插入后我无法执行任何操作,例如通过返回的 id 插入另一个数据。
这是我的示例代码:
@Dao
interface EventDao {
...
@Insert
suspend fun insert(event: Event): Long
...
}
class EventRepository(...) {
...
suspend fun insertEvent(event: Event, personId: Long) {
val id = eventDao.insertSync(event)
// !!! FREEZE - the code below here will never reach !!!
val attendee = EventAttendee(
personId = personId,
eventId = id
)
eventAttendeeDao.insert(attendee)
}
...
}
class EventEditingViewModel(...) : ViewModel() {
...
fun addEvent(event: Event) {
event.userId = userId
viewModelScope.launch {
eventRepository.insertEvent(event, friendId)
}
}
...
}
实际上,如果我删除suspend
关键字,我可以正确获取返回 id。只有当我在 Dao 类的插入方法前面使用暂停关键字时,才会发生冻结问题。
Logcat没有显示任何日志,应用程序也不会崩溃,所以我不知道发生了什么。
我的房间版本是2.2.1
,我也试过2.2.2
。
我是否以错误的方式在房间数据库中使用挂起功能?
我查看了协程库,然后发现我的插入方法已被取消,导致 ViewModel 被删除。
因为我构建了一个DialogFragment
并在单击AlertDialog
的PositiveButton
后进行插入,因此在插入完成之前视图ModelScope已经清除。
我认为解决方案可能是以下几种:
-
使用其他作用域(如
GlobalScope.launch
而不是viewModelScope.launch
-
插入后关闭对话框。
-
将数据返回到另一个片段,在另一个页面中插入。
在这种情况下,我认为最好的选择是第一选择。它更容易,并且不会导致任何其他生命周期的问题。
我和你有同样的问题,进行此实时更新的最简单方法是在您仍在对话框中时刷新活动。 在数据库中添加用户后,我添加了这些代码行(在对话框的"确定"按钮中(:
finish();
overridePendingTransition(0, 0);
startActivity(getIntent());
overridePendingTransition(0, 0);
希望对您有所帮助。它对我有用!