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

Kotlin中使用GlobalScope协程从Room数据库获取数据时ProductList始终为空的解决办法

问题分析与解决方案

核心问题

你的代码里productList始终为空,是因为协程异步执行的特性:GlobalScope.launch(Dispatchers.IO)启动的协程会在后台线程执行数据库查询,但主线程不会等待它完成,直接就走到了后续的判断逻辑,此时productList还是初始的空列表。

修复方案

1. 修改验证函数为挂起函数

将nameValidation改成挂起函数,直接在协程上下文里执行数据库查询,避免异步竞态问题:

suspend fun nameValidation(name: TextInputEditText, cactusDao: CactusDao): String? {
    val nameText = name.text.toString().trim()
    
    // 优先检查空值,减少不必要的数据库查询
    if (nameText.isNullOrEmpty()) {
        return "Field is Empty!"
    }
    
    // 直接调用Room的挂起DAO方法(Room默认DAO方法需加suspend修饰)
    val productList = cactusDao.getAllProductNames()
    return if (productList.contains(nameText)) {
        "Product already Exists!"
    } else {
        null
    }
}

2. 在调用处用生命周期安全的协程执行

在焦点变化的监听里,使用lifecycleScope(或viewModelScope)启动协程,确保异步查询完成后再更新UI:

productName.setOnFocusChangeListener { _, focused ->
    if (!focused) {
        lifecycleScope.launch {
            val errorMsg = ProductValidator.nameValidation(productName, cactusDao)
            // lifecycleScope默认在主线程执行,可直接更新UI
            productNameContainer.helperText = errorMsg
        }
    }
}

关键注意事项

  • 确保你的Room DAO方法getAllProductNames已经添加了suspend修饰符,否则无法在挂起函数中调用。
  • 避免使用GlobalScope,它的协程不受组件生命周期管控,容易引发内存泄漏;lifecycleScope会随组件生命周期自动取消协程,更安全。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 10:52:08