【问题标题】:android room suspend insert success but does not return idandroid room暂停插入成功但不返回id
【发布时间】:2020-03-30 00:55:51
【问题描述】:

我正在尝试使用带有暂停关键字的房间数据库。

我可以成功地将数据插入到数据库中。但是在那之后,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 类的插入方法前使用suspend关键字时才会出现冻结问题。

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

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

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

【问题讨论】:

    标签: android android-room kotlin-coroutines


    【解决方案1】:

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

    因为我建了一个DialogFragment,在点击AlertDialogPositiveButton后进行插入,所以在插入完成之前viewModelScope已经清晰了

    我认为解决办法可能有以下几种方式:

    1. 使用另一个作用域,例如GlobalScope.launch,而不是viewModelScope.launch

    2. 插入后关闭对话框。

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

    在这种情况下,我认为最好的选择是首选。它更容易,不会导致任何其他生命周期的问题。

    【讨论】:

      【解决方案2】:

      我和你有同样的问题,进行实时更新的最简单方法是在你还在对话框中时刷新活动。 我在数据库中添加了用户之后添加了这些代码行(在对话框的 OK 按钮中):

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-26
        • 1970-01-01
        • 2018-01-19
        • 2019-05-01
        相关资源
        最近更新 更多