Android房间暂停插入成功但不返回ID

时间:2019-12-05 06:14:50

标签: android android-room kotlin-coroutines

我正在尝试使用带有suspended关键字的会议室数据库。

我可以成功地将数据插入数据库。但是之后,插入方法将不返回任何内容,这意味着插入后我将无法执行任何操作,例如通过返回的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类的插入方法前面使用suspend关键字时,才会发生冻结问题。

Logcat不会显示任何日志,该应用程序也不会崩溃,所以我不知道发生了什么。

我的房间版本是2.2.1。而且我也尝试过2.2.2

我在房间数据库中使用挂起功能的方式有误吗?

2 个答案:

答案 0 :(得分:0)

我查看了协程库,然后发现由于删除了ViewModel,我的插入方法已被取消。

因为我建立了DialogFragment,并在点击PositiveButton的{​​{1}}之后进行插入,所以 viewModelScope在插入完成之前就已经清除

我认为解决方案可能是以下几种方式:

  1. 使用其他范围,例如AlertDialog代替GlobalScope.launch

  2. 在插入后关闭对话框。

  3. 将数据返回另一个片段,在另一个页面中插入。

在这种情况下,我认为最好的选择是第一选择。这样更容易,并且不会引起任何其他生命周期的问题。

答案 1 :(得分:0)

我遇到了与您相同的问题,进行此实时更新的最简单方法是在您仍在对话框中时刷新活动。 我在数据库中添加了用户后(在对话框的确定​​按钮中)添加了这些代码行:

finish();
overridePendingTransition(0, 0);
startActivity(getIntent());
overridePendingTransition(0, 0);

希望有帮助。它对我有用!