2


我手头有一个应用程序,我们需要在其中使用选项卡进行数据输入。该选项卡从远程服务器加载初始数据。随后,当用户在选项卡上插入/更新数据时,需要更新、插入(用于新数据)远程服务器。数据库服务器是 SQL Server 2008。
正如 stackoverflow 的许多专家所建议的那样,我们将在服务器上使用 Web 服务来促进数据交换。但是我仍然不确定以下几点 -
1. 在这种情况下,最好的身份验证机制是什么。
2.我应该从android的sqlite表中获取一大块数据,转换为JSON并将其传递给Webservices进行插入/更新操作还是获取单行并更新。虽然我认为发送单行效率不高。
3.我如何管理升级远程服务器的失败。如果我使用单行,这会更容易。我的计划是将 sqlite 记录的状态标志设置为 1(默认为 0),以便将记录更新/插入到远程服务器。如果更新/插入失败,我将状态标志改回 0,以便下次我可以再次使用它们。如果成功,将标志更改为 2。


提前致谢

更新
做一些研究并尝试使用 SampleSyncAdapter。对整个操作仍然有些困惑。我的 Sqlite 数据库是由一个程序创建的,并且该应用程序中存在内容提供程序类。应用程序的包名称是 com.xylo.pds。我正在尝试编写一个同步应用程序,它尝试同步第一个应用程序中使用的数据。如果我遵循 SampleSyncAdapter 示例 - 我需要开发服务器端应用程序进行身份验证,然后将 android 数据上传到服务器(在我的情况下,一种方式就足够了)。我可以在示例中提供的服务器端代码的帮助下做到这一点。所以我只是为我的身份验证和同步复制了示例代码的代码。我的authenticator.xml 有现有的条目- android:contentAuthority="com.android.contacts" android:accountType="com.example.android.samplesync

所以现在我的应用程序可以添加帐户并同步联系人。难怪它可以与示例中给出的虚拟服务器 ID 一起使用。
现在我需要将自己的代码放入应用程序中,以便将本地数据库加载到服务器。为此,我需要在 SyncAdapter 的 onPerformSync 中添加代码。为了使用现有的 ContentProvider,我在清单文件中有以下条目 <uses-permission android:name="com.xylo.pds.RCDataProvider" />。定义 ContentProvider 的应用程序具有以下条目 -
<provider android:name=".RCDataProvider" android:authorities="com.xylo.pds.provider" android:exported="true" android:readPermission="android.permission.permRead" />
现在,如果我在 SyncAdapter 中添加了对 contentresolver 的调用,则保持其他所有内容都相同,只是为了检查一切正常。所以,没关系,我可以更改 onPerformSync 以添加用于上传数据的代码。然而,现在应用程序停止同步联系人。我缺少什么请赐教。谢谢

4

2 回答 2

0

1)在这种情况下,最好的身份验证机制是什么。

您可以/应该使用 OAuth2。要么在 Web 服务网站上实现您自己的令牌,要么将常见的 OAuth2 Web 服务与 Android 帐户管理器结合使用。

建议这种方法的原因实际上是根据谷歌文档处理用户身份验证的建议/推荐方式。请参阅此处的“记住您的用户” http://developer.android.com/training/id-auth/identify.html

这很好地引出了你的下一个问题

2)我应该从android的sqlite表中获取一大块数据,转换为JSON并将其传递给Webservices以进行插入/更新操作还是获取单行并更新。虽然我认为发送单行效率不高。

您应该使用 android 同步适配器,它将利用我在回答问题 1 时给您的链接中描述的帐户管理器功能

您可以以任何您希望的方式对您的 android 服务进行编码,但您应该在两个方向上都使用 JSON 而不是 XML。

将帐户管理器与同步适配器一起使用的真正巧妙之处在于,您的 SQLite 内容提供程序方法可以使用 notifyChange 方法告诉同步适配器更新 Web 服务。

您可以告诉同步适配器同时从您的网络服务获取最新数据,或者您可以安排同步。

3)我如何管理升级远程服务器的失败。如果我使用单行,这会更容易。我的计划是将 sqlite 记录的状态标志设置为 1(默认为 0),以便将记录更新/插入到远程服务器。如果更新/插入失败,我将状态标志改回 0,以便下次我可以再次使用它们。如果成功,将标志更改为 2。

Virgil 在嵌入到此同步适配器教程中的 Google I/O 视频中对此进行了解释https://sites.google.com/site/andsamples/concept-of-syncadapter-androidcontentabstractthreadedsyncadapter

使用同步适配器从您的网络服务获取数据的另一种解决方案是使用 GCM(谷歌云消息传递服务。http: //developer.android.com/google/gcm/gs.html

基本上,帐户管理器/同步适配器/gcm 是 Android 推荐您使用的功能,这些是 Google 将自己用于 GMail 之类的服务,使您的用户即使在清除数据或卸载应用程序后也能够保持数据完整重新安装应用程序,它还允许用户能够在新手机上安装应用程序并保留他们的数据。

希望有帮助

更新以回应评论

您应该始终努力尽量减少在任一方向发送的数据流量和大小。我会在一个压缩后的 JSON 请求中发送全部内容。您的网络服务器应该能够自动处理 gzip 压缩的请求,如果您的服务器上没有安装 gzip,那么添加它很简单

可以在此处找到从您的应用程序创建压缩输出流的参考 http://developer.android.com/reference/java/util/zip/GZIPOutputStream.html

对于 Web 服务器,您需要的解决方案将取决于您使用的服务器,您应该与您的主机核实 gzip,但这里有一些最流行的 Web 服务器的链接

Apache - http://howtounix.info/howto/Apache-gzip-compression-with-mod_deflate NGinx 教程 - http://www.howtoforge.com/how-to-save-traffic-with-nginxs-httpgzipmodule-debian-挤

GZip 是最流行的 Web 服务器解决方案,并且实现起来非常简单。

我真的没有足够的信息来提供更多的建议,除了说我通常使用 Ruby on Rails 来处理这样的事情,并且 gzip 使用 ative 支持 gzip 库非常简单地处理,使用类似的东西contacts = ActiveSupport::JSON.decode(gzipped_contacts.gsub("+", ""))

更新 2 notifyChange()

只是为了了解您的观点,由于没有互联网访问,notifyChange 在内容提供商中不合适。

在您的内容提供程序中使用 notifyChange() 很好,因为它会告诉同步适配器在适当的时候立即更新,这意味着当设备不太忙并且互联网连接可用时。这就是同步适配器的全部意义所在。如果您需要在内容提供程序中为其他服务(例如数组适配器)使用 notifyChange,但您不希望同步适配器被告知更新,那么您可以在 notifyChange 末尾添加一些记录在案的布尔参数参数列表。将其设置为 false 并且内容提供者将忽略 notifyChange

例如,而不是通常的getContext().getContentResolver().notifyChange(uri, null);你可以使用getContext().getContentResolver().notifyChange(uri, null, false);

于 2013-05-17T07:35:49.443 回答
0
  1. a) 您可以要求用户从移动应用程序登录/注册,就像您为网站所做的那样。b)看看这个http://android-developers.blogspot.ro/2013/01/verifying-back-end-calls-from-android.html

  2. 在同一个请求中发送更多记录,这个想法是尽可能少地发出请求。

  3. 我认为您不应该将错误标志保持与默认值相同,它应该是一个不同的值,以便您能够更轻松地处理它。

于 2013-05-17T07:06:11.877 回答