【问题标题】:Need sample Android REST Client project which implements Virgil Dobjanschi REST implementation pattern需要实现 Virgil Dobjanschi REST 实现模式的示例 Android REST 客户端项目
【发布时间】:2011-02-09 17:13:13
【问题描述】:

我想在安卓手机上构建一个 REST 客户端。

REST 服务器公开了几个资源,例如(获取)

http://foo.bar/customer      List of all customer
http://foo.bar/customer/4711    The customer with id 4711
http://foo.bar/customer/vip     List of all VIP customer

http://foo.bar/company           List of all companys
http://foo.bar/company/4711     The company with the ID 4711
http://foo.bar/company/vip      List of all VIP companys

我(认为)我知道如何与 REST 服务器通信并获取我需要的信息。我会用这样的 API 实现一个 REST 客户端类

public List<Customer> getCustomers();
public Customer getCustomer(final String id);
public List<Customer> getVipCustomer();

public List<Company> getCompanies();
public Customer getCompany(final String id);
public List<Customer> getVipCompanies();

参考 Virgil Dobjanschi 的演示文稿“Developing Android REST client applications”我了解到在 Activity 的工作线程中处理 REST 请求不是一个好主意。相反,我应该使用Service API。

我喜欢拥有一个绑定到(本地)服务的 Singleton ServiceHelper 的想法,但我担心我没有正确理解服务概念。

目前我不明白如何将 REST 调用结果(在服务中异步完成)报告回调用方 Activity。我还想知道我是否需要一个服务来处理所有 REST 请求(具有不同的返回类型),或者我是否需要为每个 REST 请求提供专用服务。

可能我还有许多其他的理解问题,所以对我来说最好的事情是满足我的需求的示例应用程序。我的用例并不少见,我希望那里有示例应用程序。

请告诉我!

指出我正确实施方向的任何其他建议也很有帮助(Android API-Demo 与我的用例不匹配)。

提前致谢。

克劳斯

编辑:在 SO 上找到的类似主题(发布后)将我引向我需要的方向(最小化复杂的“Dobjanschi 模式”):

【问题讨论】:

  • Claszen,您是否对所有请求的单一服务与每个请求的专用服务有任何意见?如果可以,请分享。以我为例的场景:我有很多 REST 请求 [大约 20 个] 要在我的应用程序中使用。我已经观看了上面提到的 Google I/O 中的宝贵会议。我的问题是,哪种方法更好。让单一服务​​处理单一服务中的所有请求?还是为每个请求提供专门的服务?我有一些应该按顺序触发的请求,其中一些可以同时触发。有什么建议吗?
  • @user778869 我终于为每个(“顶级”)REST 资源(如“公司”、“客户”)使用了一个 IntentService 和 ResultReceiver。我发现这是一种“自然”的结构,效果很好。它可能会产生一些代码重复,但如果它在一个服务中完成,则可以防止过多地使用控制结构。
  • 这可能对学习 Android REST 客户端实现的人很有帮助。 Dobjanschi 的演示文稿转录成 PDF:drive.google.com/file/d/0B2dn_3573C3RdlVpU2JBWXdSb3c/…

标签: java android design-patterns rest


【解决方案1】:

概览

编辑:

任何有兴趣的人也可以考虑看看RESTful android,这可能会让你更好地了解它。

我从尝试实施 Dobjanschi 模型的经验中学到的是,并非一切都是一成不变的,他只为您概述了如何做这可能会因应用程序而异,但公式是:

遵循这个想法 + 添加你自己的 = 快乐的 Android 应用程序

某些应用程序的模型可能因要求而异,有些应用程序可能不需要 SyncAdapter 的帐户,其他应用程序可能使用 C2DM,我最近工作的这个可能会帮助某人:


创建具有 Account 和 AccountManager 的应用程序

它将允许您使用 SyncAdapter 来同步您的数据。这已经在Create your own SyncAdapter讨论过

创建一个ContentProvider(如果它适合您的需要)

这种抽象允许您不仅可以访问数据库,还可以通过 ServiceHelper 执行 REST 调用,因为它具有与 REST Arch 的一对一映射方法。

内容提供者 | REST 方法

查询 ----------------> 获取

插入 ----------------> 放置

更新 ----------------> 发布

删除 ----------------> 删除

ServiceHelper 分层

这个人基本上会使用您从 ContentProvider 传递的参数启动 (a) 服务,这些服务执行 Http(不一定是协议,但它是最常见的)REST 方法。我传递了从内容提供程序上的 UriMatcher 获得的匹配整数,所以我知道要访问什么 REST 资源,即

class ServiceHelper{

    public static void execute(Context context,int match,String parameters){
//find the service resource (/path/to/remote/service with the match
//start service with parameters 
    }

}

服务

被执行(我大部分时间都使用 IntentService),它使用从助手传递的参数进入 RESTMethod,它有什么用?请记住,服务很适合在后台运行。

还实现一个广播接收器,这样当服务完成它的工作时,通知我的活动注册了这个广播并再次重新查询。我相信这最后一步不在 Virgill Conference 上,但我很确定这是一个不错的选择。

RESTMethod 类

取参数,WS资源(http://myservice.com/service/path)添加参数,准备好一切,执行调用,保存响应。

如果需要 authtoken,您可以向 AccountManager 请求 如果服务调用因为身份验证失败,您可以使 authtoken 失效并重新获得一个新的令牌。

无论我基于匹配器创建处理器并传递响应,RESTMethod 最终都会给我一个 XML 或 JSON。

处理器

它负责解析响应并在本地插入。

示例应用程序?当然!

此外,如果您对查看Eli-G 的测试应用程序感兴趣,它可能不是最好的示例,但它遵循Service REST 方法,它是使用ServiceHelper、Processor、ContentProvider、Loader 和Broadcast 构建的。

【讨论】:

  • 感谢您的回答。我最终为每个(“顶级”)REST 资源(如“公司”、“客户”)使用了一个 IntentService 和 ResultReceiver。 Dobjanschi 模型对我来说太重了。
  • 好吧 b 使用 IntentService 和 ResultReseiver 你可能使用第一个描述场景,这是一个服务驱动模型,虽然他使用 Binder 而不是 ResultReceiver 进行通信,但这很好,正如我所说的不是一成不变的!.
  • 前段时间我问了这个问题,我找到了适合我的解决方案。我无法检查对示例应用程序的所有引用 - 但由于这是最新的答案,我会接受它。不过,我建议您也检查所有其他答案。
  • 优秀的建议,检查所有答案,他们都有很多好的资源和想法!就像 Jeremy 的 Android 编程书籍 Yoni 和 iosched 源代码一样。
  • @Necronet 您好,刚刚偶然发现了您很有前途的示例应用程序-但是,我在构建它时遇到了麻烦。你介意告诉我们它必须针对哪个版本的 ActionBarSherlock 构建(似乎它不适用于最新的 ABS 4.1)?另外,从您的帖子中,我并没有真正找到您所针对的 Dobjanschi 模型的哪种模式(A、B 或 C)(我知道,您可能最终会出现一些变化,但我想您主要关注其中一个模式 - 我想模式 B?)谢谢!
【解决方案2】:

Programming Android 有一整章(13. 探索内容提供者)专门讨论 Virgil 的 Google I/O 演讲中的“选项 B:使用 ContentProvider API”。

我们并不是唯一看到这种方法的好处的人。在 2010 年 5 月的 Google I/O 大会上,Google 的 Virgil Dobjanschi 发表了演讲,概述了使用内容提供者将 RESTful Web 服务集成到 Android 应用程序的以下三种模式...

在本章中,我们将通过第二个 Finch 视频示例详细探讨第二种模式;此策略将为您的应用程序带来许多重要的好处。由于这种方法将网络操作集成到 Android MVC 中非常优雅,因此我们将其命名为“Network MVC”。

Android 编程的未来版本可能会介绍其他两种方法,并记录此 Google 演示文稿的更多详细信息。阅读完本章后,我们建议您查看 Google 的演讲。

强烈推荐。

Zigurd Mednieks、Laird Dornin、G. Blake Meike 和 Masumi Nakamura 编写的 Android 编程。版权所有 2011 O'Reilly Media, Inc., 978-1-449-38969-7。

【讨论】:

    【解决方案3】:

    Virgil Dobjanschi 的“开发 Android REST 客户端应用程序”引起了很多讨论,因为在会议期间没有提供任何源代码,也没有在之后提供。

    • http://datadroid.foxykeep.com 下提供了参考实现(/presentation 下提到了 Google IO 会话)。它是一个您可以在自己的应用程序中使用的库。
    • Android Priority Job Queue 的灵感来自于 Dobjanschi 的演讲,对我来说听起来很有希望。

    如果您知道更多实现,请发表评论。

    【讨论】:

    • 感谢分享这个可能有用的链接(目前没有机会深入了解)
    • 这看起来像是一个解决方案。谢谢!
    【解决方案4】:

    我们开发了一个解决此问题的库:RoboSpice

    该库使用Virgil DobjanschiNeil Goodmann 描述的“服务方法”,但我们提供了一个完整的一体化解决方案:

    • 异步执行(在后台 AndroidService 中)网络 将返回 POJO 的请求(例如:REST 请求)
    • 缓存结果(在 Json、或 Xml、或纯文本文件或二进制文件中)
    • 通知您的活动(或任何其他上下文)网络的结果 询问他们是否还活着
    • 不通知您的活动 如果他们不再活着,结果
    • 通知您的活动 他们的 UI 线程
    • 使用简单但强大的异常处理模型
    • 支持多个 ContentService 聚合不同的 Web 服务 结果
    • 支持请求执行的多线程
    • 强烈 打字!
    • 是开源的 ;)
    • 并经过测试

    我们实际上是在寻找来自社区的反馈。

    【讨论】:

      【解决方案5】:

      改造在这里可能会很有帮助,它通过一个非常简单的配置为您构建一个适配器,例如:

      Retrofit 将您的 REST API 转换为 Java 接口。

      public interface GitHubService {
        @GET("/users/{user}/repos")
        List<Repo> listRepos(@Path("user") String user);
      }
      

      RestAdapter 类生成 GitHubService 接口的实现。

      RestAdapter restAdapter = new RestAdapter.Builder()
          .setEndpoint("https://api.github.com")
          .build();
      

      GitHubService 服务 = restAdapter.create(GitHubService.class); 对生成的 GitHubService 的每次调用都会向远程 Web 服务器发出一个 HTTP 请求。

      List<Repo> repos = service.listRepos("octocat");
      

      欲了解更多信息,请访问官方网站:http://square.github.io/retrofit/

      注意:您从 Retrofit 获得的适配器 RestAdapter 不是从 BaseAdapter 派生的,您应该为它制作一个包装器,就像这个 SO question Why is my ListView empty after calling setListAdapter inside ListFragment?

      【讨论】:

      【解决方案6】:

      这有点晚了,但这里有一篇文章解释了谈话中的第一个模式:

      http://www.codeproject.com/Articles/429997/Sample-Implementation-of-Virgil-Dobjanschis-Rest-p

      我喜欢第一种模式的一点是,其余方法的接口是一个普通类,而 Content Provider 仅用于提供对数据库的访问。

      【讨论】:

        【解决方案7】:

        对于初学者,您应该查看 Google 官方 I/O 2010 app 的源代码,尤其是 SyncServiceio subpackage 中的各种类。

        【讨论】:

        • +1 不是我的用例,但无论如何是一个很好且有用的 Android 应用程序示例。谢谢!
        【解决方案8】:

        好消息伙计们。 此处提供了服务助手的实现:https://github.com/MathiasSeguy-Android2EE/MythicServiceHelper 这是一个开源项目(Apache 2)。 我在项目的开始。我已经完成了一个项目,我在其中定义了要执行的模式,但我还没有提取代码来制作一个干净的库。 很快就会完成。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-01-06
          • 1970-01-01
          • 2017-11-20
          • 2021-05-12
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多