在Android App和网络服务器之间同步数据

时间:2012-05-31 07:43:48

标签: android android-syncadapter data-sharing

我想在Android App和服务器之间同步数据(例如db记录,媒体)。如果你看过Evernote或类似的应用程序,你当然明白我的意思。

我有一些问题(想象一下我们想要同步DB记录):

  1. 每个用户都有自己的部分服务器空间(例如EvernoteDropbox)。也许用户通过手机创建新记录并在服务器中创建新记录。 如何将这些记录匹配在一起?如果有相同ID的记录您建议我使用哪种算法?

  2. JSON 除外,有没有办法在手机设备和服务器之间发送数据?

  3. 如果 SyncAdapter ContentProvider 可以解决我的问题,请完全为我解释。 (如果您可以向我提供一些示例或教程,或者任何建议或关键词以帮助扩大/指导我的搜索也将受到赞赏。

9 个答案:

答案 0 :(得分:301)

我会尝试通过解决更大的问题来回答您的所有问题: 如何在网络服务器和Android应用之间同步数据?


在您的网络服务器和Android应用之间同步数据需要Android设备上的几个不同的组件。

持久存储:

这就是您的手机实际存储从网络服务器接收的数据的方式。实现此目的的一种可能方法是编写由Sqlite数据库支持的自定义 ContentProvider 。可以在此处找到适合内容提供商的体面教程:http://thinkandroid.wordpress.com/2010/01/13/writing-your-own-contentprovider/

ContentProvider 定义了一个与您存储的数据进行交互的一致界面。如果您愿意,它还可以允许其他应用程序与您的数据进行交互。 ContentProvider 后面可能是Sqlite数据库,缓存或任意存储机制。

虽然我当然建议在Sqlite数据库中使用 ContentProvider ,但您可以使用任何基于Java的存储机制。

数据交换格式:

这是您用于在网络服务器和Android应用之间发送数据的格式。目前最流行的两种格式是XML和JSON。在选择格式时,您应该考虑哪种序列化库可用。我知道,有一个非常棒的json序列化库叫做gson:https://github.com/google/gson,虽然我确信XML存在类似的库。

同步服务

您需要某种异步任务,可以从您的服务器获取新数据并刷新移动内容以反映服务器的内容。每当您对内容进行本地更改并希望反映这些更改时,您还希望通知服务器。 Android提供 SyncAdapter 模式作为轻松解决此模式的方法。您需要注册用户帐户,然后Android会为您执行大量的魔术,并允许您自动同步。这是一个很好的教程:http://www.c99.org/2010/01/23/writing-an-android-sync-provider-part-1/


至于如何识别记录是否相同,通常您将创建具有唯一ID的项目,您可以将它们存储在Android设备和服务器上。您可以使用它来确保您引用相同的参考。此外,您可以存储列属性,例如" updated_at"确保您始终获得最新鲜的数据,或者您不会意外地写下新写入的数据。

答案 1 :(得分:54)

如果我们考虑今天accepted answer太旧了。我们知道我们有许多新的库可以帮助您制作这类应用程序。

您应该学习以下可以帮助您的主题:

  • SyncAdapter:应用中的同步适配器组件封装了在设备和服务器之间传输数据的任务的代码。根据您在应用中提供的计划和触发器,同步适配器框架运行同步适配器组件中的代码。

  • Realm:Realm是一个移动数据库:SQLite&的替代品。核心数据。

  • Retrofit Square,Inc。的Android和Java类型安全的HTTP客户端必须学习a-smart-way-to-use-retrofit

您的数据库同步逻辑如:How to sync SQLite database on Android phone with MySQL database on server?

祝所有新学员好运。 :)

答案 2 :(得分:24)

如果你自己写这些是要牢记的一些要点

设备与同步服务器之间的正确身份验证

设备和服务器之间的同步协议。它通常分为3个阶段,认证,数据交换,状态交换(哪些操作有效,哪些失败)

选择您的有效负载格式。我建议基于SyncML的XML与基于JSON的格式混合来表示实际数据。因此协议的SyncML和正在交换的实际数据的JSON。在操作数据时使用JSON数组总是首选,因为使用JSON数组很容易访问数据。

跟踪客户端和服务器上的数据更改。您可以维护更改的更改日志,这些更改会在同步会话期间进行更改和提取。此外,在对象成功同步时清除更改日志。您还可以使用布尔变量来确认同步状态,即上次同步。最终用户可以确定上次同步的时间。

当服务器上的数据发生变化时,需要有办法从服务器与设备通信以启动同步会话。您可以使用C2DM或编写自己的基于持久性tcp的通信。 tcp方法很无缝

跨多个设备复制数据更改的方法

最后但并非最不重要的是,一种检测和处理冲突的方法

希望这有助于作为一个良好的起点。

答案 3 :(得分:13)

@Grantismo对整体提供了很好的解释。如果你想知道谁在实际做这件事,我建议你去看看谷歌为2014年的谷歌IO应用程序做了什么(总是值得深入了解他们发布的这些应用程序的源代码。这里有从那里可以学到很多东西。)

以下是关于它的博文:http://android-developers.blogspot.com.br/2014/09/conference-data-sync-gcm-google-io.html

基本上,在应用程序方面:GCM用于信令,同步适配器用于数据获取和与内容提供商正确交谈,这将使事情持久(是的,它将数据库与应用程序的其他部分直接访问隔离)。

另外,如果您想查看2015年的代码:https://github.com/google/iosched

答案 4 :(得分:7)

例如,您想要将todoTable的表MySql同步到Sqlite

首先,为version (type INT)todoTableSqlite中创建一个列名MySql enter image description here

其次,创建一个包含一个列名database_version的表名currentVersion(INT) enter image description here

MySql中,当您向todoTable或更新项目添加新项目时,您必须将此项目的版本升级+1,同时升级{{ 1}} enter image description here

currentVersion中,当您要同步时(通过手动按下同步按钮或​​具有期间的服务运行):

您将使用Android currentVersion(当前为1)向服务器发送请求 然后在服务器中,您会发现Sqlite中的哪个项目的版本值大于MySql currentVersion(1)然后对Android的响应(在此示例中,版本2的项目3将响应Android)

Sqlite中,您将新项目添加或更新为SQLite并升级currentVersion

答案 5 :(得分:6)

看看parseplatform.org。 这是开源项目。

(除了你可以在back4app.com获得商业套餐。)

这是一个非常直接且用户友好的服务器端数据库服务,它提供了一个很棒的Android客户端API

答案 6 :(得分:3)

实现此目的的一种方法是让服务器端应用程序等待数据。可以使用Java中的HttpRequest对象发送数据,也可以编写自己的TCP/IP数据传输实用程序。数据可以使用JSON格式或您认为合适的任何其他格式发送。如果数据包含敏感信息,也可以在发送到服务器之前加密数据。所有服务器应用程序必须做的只是等待HttpRequests进入并解析数据并将其存储在任何你想要的地方。

答案 7 :(得分:1)

我建议使用类似于Hessian的二进制Web服务协议。它工作得很好,他们确实有一个Android实现。它可能有点重,但取决于您正在构建的应用程序。希望这会有所帮助。

答案 8 :(得分:1)

@Grantismo概述了Android同步组件。

SyncManagerAndroid库提供了一个简单的双向同步实现,可插入Android Sync框架(AbstractThreadedSyncAdapter.OnPerformSync)。

https://github.com/sschendel/SyncManagerAndroid