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
相关产品推荐
相关产品推荐

