14

这更多是一个概念问题,不一定与任何特定技术有关。假设您在服务器上有一些数据库,一些 REST/JSON API 来访问该数据库中的内容,以及一些显示通过 API 检索的数据的移动客户端。

最好在客户端上有一些缓存机制,并且只要客户端只读取数据就能够启用对数据的脱机访问(在我的情况下,拒绝对脱机客户端的写访问是很好的,以避免不得不管理所有可能发生的令人讨厌的冲突)。

似乎解决这个问题的一个好方法是在客户端上存在服务器数据库模型的一个子集,并将数据从服务器同步到客户端。对本地数据库的访问可能会立即返回结果,但也会触发对服务器的更新请求。如果服务器返回修改后的数据,客户端模型会同步它的本地数据库并通知数据更改的显示。

最终的目标当然是用户可以浏览信息而不管他的互联网连接的稳定性,并且只要他不修改任何数据,就不会被连接对话框或类似内容所困扰。

现在从实现的角度来看......一方面,将服务器数据库直接耦合到客户端数据库似乎是一个坏主意,因为它们可能来自不同的供应商。我想至少在两个数据库实现之上都需要一个独立于供应商的模型。另一方面,将服务器数据库中的数据转换为某种传输格式,然后再将其放回客户端数据库似乎需要很多开销。

任何建议如何以优雅和可维护的方式解决这个问题?

4

2 回答 2

10

我正在开发一个将大型数据库的一小部分本地同步到手机上的应用程序。必须在手机上进行初始预加载,但之后更新在后台异步进行。

首先,强烈建议使用 JSON 或 XML 将服务器和手机解耦。锁定一种技术总是会导致问题,因为无论平台如何,您都被迫使用相同的技术。也就是说,如果您计划扩展到其他平台(Web、iOS 等),您将被迫使用服务器指定的格式。从长远来看,选择通用格式将使这一切变得更简单。实际上,随着公共图书馆数量的增加,读/写 JSON 是一件小事。

我们使用两种方式来同步数据;

1.报警管理器

我们安排 AlarmManager 以定期触发服务唤醒(假设每 6 小时)。唤醒启动与服务器联系的后台服务,以 JSON 格式下载更改并更新本地 SQLite DB。如果没有连接,则跳过更新并安排下次唤醒。我们添加了一个 ConnectivityChanged 接收器,以在连接恢复时自动重新启动同步。

2. GCM

如果仅在发生更改时更新本地数据库,则工作量会增加一些,但可以节省大量电池和数据使用量。Google Cloud Messaging 可以向设备发送唤醒消息并告诉它启动同步服务。同步服务的运行方式与上面的 AlarmManager 方法相同。

根据您需要数据的“新鲜程度”以及数据更改的频率,我们会结合使用上述两种方法。像 RSS 提要这样的东西可能应该每 30 分钟更新一次,而天气数据可能不需要每 4 小时更新一次。

所以要运行我们使用的数据库同步;

接收器 -> 监听系统事件并触发服务服务 -> 连接到服务器,下载 JSON 并更新 SQLite 提供者 Providers -> 将记录插入数据库并将内容更改广播到 ContentObservers ContentObservers -> 当应用程序运行时, ContentObservers 使用新数据更新 UI

上面的每个组件都有很多技术细节,但这应该为您提供一个非常强大的架构,用于将服务器数据与本地数据库同步。

于 2013-01-24T20:48:11.483 回答
5

我正在做一个有类似要求的项目。我们希望在某处的服务器上拥有一个可用的大型数据库,然后移动设备从中获取数据。如果设备离线也没关系,因为他们已经在本地保存了自己的数据副本。

我们决定使用 BigCouch(支持集群的 Apache CouchDb 的分支)作为服务器技术,然后在移动设备上使用 Couchbase Mobile。(需要注意的是,TouchDB for Android 将取代 Couchbase Mobile,但它还不稳定。)

我们采用 Couch* 技术的原因是 Couch 通过 HTTP 具有良好的复制能力。您可以在移动设备上以编程方式启动同步事件,它将为您复制所有插入、更新和删除。它将信息存储在移动设备上自己的嵌入式 CouchDb 上,因此可以离线阅读。

如果您不想走 Couch 之路,您可以简单地使用 SQLlite 之类的东西来存储 REST/API 调用的结果。然后,您必须编写自己的复制逻辑,用于移动设备何时脱机然后又回来。有一些创造性的方法可以做到这一点,所以也许这是一个选择。

于 2013-01-18T17:38:34.203 回答