使用工作管理器更新网络请求的逻辑

问题描述

我有一个从 API 获取数据的应用程序。所以基本上,现在,该应用程序是这样工作的:

  • 如果连接到互联网,获取数据并使用 Android Room 存储以供离线使用
  • 如果未连接到互联网,请检查 Room 中是否存在数据。如果存在,则显示它。如果不存在,则显示错误消息。

我在网上做了一些关于如何实施高效的离线存储策略的研究,Google 建议使用工作管理器对请求进行排队,然后在连接时发送。

我实际上想知道如何实现这一点? (不是代码而是逻辑,即我应该每天安排对 API 的请求还是每次它连接到互联网时?)

如果有离线应用经验的人可以提供帮助,那就太好了。

我的网络请求是通过 Retrofit 完成的,我已经创建了一个执行 API 调用的类。

解决方法

请记住,WM(工作管理器)旨在在满足某些条件时执行操作(例如:用户有足够的电池、显示屏关闭等)。因此,这最终可能会导致您的数据在您需要时没有更新。 WM 适用于您希望发生的操作,但对于“立即”发生并不重要。我会说始终使用 Room DB 作为唯一的事实来源。如果数据在房间里,就显示它,如果没有,就取它,如果你不能,那么,你试过了。向用户发送消息。您可以使用 NetworkConnectivityListener 来监控连接并检查您是否有待处理的查询(您可以将此查询的参数存储在 Room 数据库中的另一个表中以方便使用)。因此,您需要查询数据库,获取待处理的查询(如果有)并执行它们,更新数据,然后让 ViewModel/Repository 决定是否有上下文来显示此数据 (UI)。

我觉得你已经很接近实现你所需要的了。

换句话说:

UI:观察其 viewModel 的某个 sealed class xxx 状态以告诉它做什么(显示空列表、显示错误、将数据传递给 recyclerview 适配器等)。

ViewModel:使用其 viewModelScope.launch { ... } 将调用 repository.fetch(...) 或类似的。当 Fragment 告诉它这样做时(例如用户按下按钮)或某个生命周期事件(例如 onStart),您的 viewModel 将获取这些数据。

在这种情况下,Repository 通常公开一个 flow(如果您可以使用实验性 api)或一个可以执行以下操作的挂起函数(可能会因您的业务规则而异)

  1. 如果数据在数据库中可用,立即返回。
  2. 如果数据是旧的(或者我们仍然想刷新它),那么执行网络 API(如果有连接的话)。如果没有连接,您可以将此“待处理”查询存储在数据库中以备后用。您还可以在执行任何操作之前检查您是否有待处理的查询,可能它已经过时,或者您可能需要执行它。
  3. 无论如何,一旦查询通过,您就将结果插入到数据库中,并调用您在第 1 步中使用的相同方法。
  4. 如果您有查询(或使用此查询),请不要忘记更新您的“待处理”查询。

使用 WorkManager,您可以安排“从 API 获取数据”部分在某个时间发生(这样您的数据将保持更新),但我完全取决于您拥有的用例。

>

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...