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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 22:15:28