You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中使用Coroutines在Room存储数据失败,求原因及解决方法

问题分析与解决方案

核心错误点

1. Dao层参数引用错误

在setNewDataListWithDelete方法中,你定义的参数是datas: List<DataRoom>,但调用insertAllData时误用了未定义的变量data,导致删除旧数据后没有传入任何要插入的新数据:

@Transaction
open suspend fun setNewDataListWithDelete(datas: List<DataRoom>) {
    deleteAllData()
    insertAllData(data) // 此处应为datas,而非data
}

这是数据库为空的直接原因——删除操作执行了,但插入操作没有实际数据传入。

2. 协程作用域风险

saveDataToRoom中使用GlobalScope.future存在隐患:

  • GlobalScope的协程不受组件生命周期管控,如果当前页面或组件销毁,协程可能被中途取消,导致数据插入流程中断。
  • 建议替换为绑定生命周期的协程作用域,比如ViewModel用viewModelScope,页面用lifecycleScope。

3. 空值处理缺失

ResponseData中的data是可空类型,Java侧调用response.body().getData()可能返回null,直接传入用例会导致后续流程无数据可插入。需要先做判空处理:

List<DataRoom> dataList = response.body().getData();
if (dataList != null && !dataList.isEmpty()) {
    repo.getValue().saveDataToRoom(dataList);
}

修复后的代码示例

修正Dao层方法

@Transaction
open suspend fun setNewDataListWithDelete(datas: List<DataRoom>) {
    deleteAllData()
    insertAllData(datas) // 修正参数名
}

替换协程作用域(以ViewModel为例)

fun saveDataToRoom(data: List<DataRoom>) {
    viewModelScope.launch {
        insertAllDataUseCase.build(data)
    }
}

完善Java侧空值判断

ResponseData responseBody = response.body();
if (responseBody != null) {
    List<DataRoom> dataList = responseBody.getData();
    if (dataList != null && !dataList.isEmpty()) {
        repo.getValue().saveDataToRoom(dataList);
    }
}

额外排查点

  • 确认DataRoom实体类的@Entity注解配置正确,表名、字段与Dao层SQL语句完全匹配。
  • 检查BaseUseCase的build方法逻辑,确保没有拦截或丢弃传入的data参数。

内容的提问来源于stack exchange,提问作者chrisChris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 14:20:28