Android Kotlin Room获取唯一分组名并在RecyclerView显示问题求助
问题解决指南
1. 修正DAO方法的返回类型错误
你的findallgroup()仅查询Group_name单个字段,但返回类型写的是List<Lesson>,Room无法将单字段结果映射为完整的Lesson对象,这是隐藏的核心问题:
@Dao interface LessonDao { @Query("SELECT * FROM lesson_table") fun getAll(): List<Lesson> // 将返回类型改为List<String>,与查询的字段匹配 @Query("SELECT DISTINCT Group_name FROM lesson_table") fun findallgroup(): List<String> }
2. 解决线程异常问题
Android规定UI操作必须在主线程执行,你用GlobalScope.launch默认在后台线程运行,直接调用adapter.addItems触发UI更新就会抛出异常,需要切换到主线程执行UI操作:
private fun init(){ binding.apply { gridLayoutManager = GridLayoutManager(requireContext(), 2, LinearLayoutManager.VERTICAL, false) rcView.layoutManager = gridLayoutManager rcView.adapter=adapter } GlobalScope.launch(Dispatchers.IO) { // 在后台IO线程执行数据库查询 val groupNames = appDb.lessonDao().findallgroup() // 切换到主线程更新Adapter launch(Dispatchers.Main) { adapter.addItems(groupNames) } } }
注意:如果你的
addItems方法内部调用了notifyDataSetChanged()这类刷新UI的方法,必须确保这一步在主线程执行,否则必然触发线程异常。
3. 适配Adapter的数据类型
现在传入的是字符串列表,需要修改Adapter的addItems方法参数为List<String>,并在ViewHolder中正确展示分组名称内容。
额外建议
- 避免使用
GlobalScope,推荐使用ViewModel绑定的CoroutineScope,更符合Android架构规范,可避免内存泄漏 - 可以将DAO方法改为挂起函数,更贴合协程使用规范:
@Query("SELECT DISTINCT Group_name FROM lesson_table") suspend fun findallgroup(): List<String>
内容的提问来源于stack exchange,提问作者Gelio
相关产品推荐
相关产品推荐

