android - 您如何处理移动应用程序中的陈旧缓存记录

标签 android sqlite rest mobile synchronization

我正在创建一个使用 REST API 的 Android 应用程序(我的第一个应用程序)。 我使用后台作业来获取内容,并且我计划使用带有 from_id 参数的 GET 请求来获取更多内容。当然,从 API 获取的任何内容都会存储在 SQLite 数据库中(我正在使用 greendao),并且该应用程序仅使用已经存在的数据,以便快速。

因此,问题是:如果在服务器上更新给定记录会发生什么情况?如果读取的记录被缓存,应用程序怎么会注意到有更改要同步?哪些策略是可行的解决方案?

谢谢。

编辑:

正如 Satish P 在他的回答中指出的那样,客户端-服务器通信是使用 ETag 处理的(我必须添加使用 If-Modified-Since 的可能性)。

但我主要关心的是如何将其与应用程序 UI 相结合。给出这个例子:

  1. 元素列表,这些元素已从 REST 服务中检索,但客户端从本地数据库中读取以使应用响应更快。
  2. 用户点击其中一个元素,会显示详细 View 。同样,数据是从本地数据库加载的。我猜此时请求了针对特定记录的 GET 请求,使用 ETag 或 If-Modified-Since header 。
  3. 碰巧服务器返回了一条修改过的记录,因此本地数据也被修改了,所以现在是时候更新用户看到的任何内容了。

问题:如果详细 View 已经填充,因为在远程请求返回时本地数据库读取已经完成,我该如何更新 View ?我认为仅用较新的数据替换当前数据是 Not Acceptable ,用户会突然看到变化。

最佳答案

就您需要服务器执行的操作而言,Satish 的回答绝对正确。要点是它需要支持 ETag 和 304 响应代码,以防内容自上次从服务器获取以来没有改变。现在在客户端,基本上可以遵循三种策略(每种策略各有利弊):

  1. 仅在内容未更改时才使用缓存。这意味着您将始终发出请求并向用户显示进度条。如果服务器返回 304,那么你的内容没有改变,请求会很快(你看到的那一刻,你显示缓存的内容)。如果服务器实际返回新内容,则继续显示进度条,并在加载内容时显示新内容。这样做的好处是用户只会看到有效的内容,因此避免了您的很多麻烦。糟糕的是,该应用程序的显示速度并没有那么快(尤其是在内容已更改且您的连接速度非常慢的情况下)。
  2. 在预定义的时间段内仅使用缓存,然后回退到第一种情况。有几个缓存 header 来定义该时间段(“max-age”和“Expires”)。在那之前你总是使用缓存(不做请求),之后你做一个请求,看看内容是否改变了。这种方法的好处是,在上述期间,应用程序非常快。不好的是,用户可能会看到不正确的内容。
  3. 在预定义的时间段内同时使用缓存和网络,然后回退到第一种情况。您可以以不同的方式使用前面提到的缓存 header 。您不仅可以显示缓存的内容,还可以实际显示缓存的内容并在后台执行请求。如果该请求返回 304,没问题,否则您将不得不使用新数据更新您的 UI(预计有两个响应,一个包含缓存数据,一个包含新检索的数据)。这样做的好处是您可以获得快速体验和有效数据(大部分时间)。不利的是,您会为您的应用增加很多复杂性(如果用户与陈旧数据交互,然后出现第二个响应,会发生什么情况等)。

总而言之,每种策略都是有效的,具体取决于用例。例如,如果用户无法与显示数据的屏幕(如电视节目)交互,则第三个选项非常好。如果用户看到正确的数据(比方说财务应用程序)至关重要,那么第一个选项是最好的。如果速度比拥有最新数据(游戏或其他)更重要,那么第二个选项是您的最佳选择。

关于android - 您如何处理移动应用程序中的陈旧缓存记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25694168/

相关文章:

android - 在我的真实手机上使用 android google map 只显示没有 map 的网格

java - 显示从数据库存储和读取的日期

asp.net - 网络 API 2 : NotFound() with content?

rest - 在PowerShell中检查Rest Call是否成功

spring - 端点按资源 swagger 注释分组?

java - 如何使用 jsoup 文档将 child 添加到子节点

android - 要为 Android Activity 设置半透明背景?

java - 启动画面取决于点击继续

java - 如何创建加密的 Jar 文件?

sql - 操作错误: near ",": syntax error - SQLITE3