MVVM架构搭配Room使用时RecyclerList无数据且无报错如何解决
问题排查与解决方案
1 核心问题1:Dao层增删改方法未加suspend修饰
你当前定义的insertPlant、delete、updatePlant方法没有添加suspend关键字,Room默认不允许在主线程执行数据库写入操作,如果你在新增数据页面没有主动切换到IO线程调用写入方法,写入操作会直接失败且如果没有捕获异常就会出现"写不进数据也不报错"的情况,修改Dao层代码如下:
@Dao interface PlantOperations { @Query("SELECT * FROM Plant") fun getAll(): Flow<List<Plant>> @Insert suspend fun insertPlant( plant: Plant) @Delete suspend fun delete(plant:Plant) @Update suspend fun updatePlant(plant:Plant) }
所有调用这些方法的位置都需要放在协程IO域中执行。
2 核心问题2:未验证数据库是否存在数据
当前代码仅实现了查询逻辑,没有预置数据也没有验证插入结果,你可以先在Repository初始化阶段添加测试插入代码,验证查询链路是否正常:
init { CoroutineScope(Dispatchers.IO).launch { // 插入测试数据,参数替换为你的Plant实体类对应字段值 plantDAO.insertPlant(Plant(name = "测试植物", type = 测试类型, image = R.mipmap.xxx)) plantDAO.getAll().collect{ allPlants.postValue(it) } } }
3 辅助排查手段
在Fragment的Observer回调中添加日志,确认数据链路是否通顺:
plantViewModel.allPlants.observe(viewLifecycleOwner, Observer { // 打印返回的列表长度,判断是无数据还是渲染问题 Log.d("ROOM_TEST", "查询到的植物列表长度:${it.size}") photoAdapter.setDataList(it) })
如果打印长度为0:确认你的
Plant实体类添加了@Entity(tableName = "Plant")注解,字段和查询语句匹配,同时确认插入操作确实执行成功如果打印长度大于0:检查RecyclerView的布局宽高是否设置正确,item布局的根布局不要用wrap_content导致无法渲染
可选优化点
当前你使用未绑定生命周期的CoroutineScope容易造成内存泄漏,建议将Repository的收集逻辑放到ViewModel的viewModelScope中执行。
内容的提问来源于stack exchange,提问作者Edita Komarova
相关产品推荐
相关产品推荐

