如何正确显示 Google Room 使用的异步任务的进度

How to properly show progress of async tasks used by Google Room

我正在使用 Google Room 在我的 Android 应用程序(Kotlin 代码)中实现数据持久化。 Room 要求所有操作(对数据库的查询)都是异步的。我希望用户等待操作执行,防止他与查询结束前未正确配置的组件进行交互。我怎样才能做到这一点,因为我无法从异步任务访问 UI 线程?

PS:我还对 API 进行了一些调用,其中 progress/loading 指标会很好。我在这些调用中使用了 RxJava,但我对这项技术还很陌生,我不确定如何正确构建它。

数据库操作示例:

private fun getDataFromCache() {
  //show progress indicator here
        execute({
            try {
                //Get items from cache
                val entities = daoData.findAll()

                if (entities.isNotEmpty()) {
                    //do something
                } else {
                    //do something else
                }
            }
            catch (e: Exception){
                Log.e("error", e.toString())
            }
            finally{
                //dismiss progress indicator here
            }
        })
    }

为了防止用户在获取过程中使用该应用程序,您可以使用像 KProgressHUD 这样的库来显示模态用户界面阻塞 HUD,它可以选择包含一个进度指示器。您只需要将 show progress indicator here 注释替换为模态 HUD 创建,将 //dismiss progress indicator here 替换为删除 UI 线程上的 HUD。

关于进度,您必须在 execute 代码中手动更新 HUD 进度。首先,您需要将您的 dao findAll() 调用拆分为 returns 您拥有的元素总数(一些 SELECT COUNT(*) 查询),以了解总进度条可能有多长。然后,您需要创建对数据库的 batched/paged 调用,而不是 findAll(),在循环中获取 N 条记录。在此循环中,您可以使用当前循环进度与开始前获得的总计数的百分比更新 HUD。

我对房间 API 不熟悉,所以我不能在这样的循环中提供任何伪代码,但通常这一切都归结为打开一个 SQL 游标并保持循环获取批量数据,直到用完为止,跟踪您读取了多少项并将它们累积在列表中。