需要实现Virgil Dobjanschi REST实现模式的示例Android REST Client项目


82

我想在Android手机上构建REST客户端。

REST服务器公开了多个资源,例如(GET)

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 Client类

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的演示“开发Android REST客户端应用程序”,我了解到在Activity的Worker Thread中处理REST请求并不是一个好主意。相反,我应该使用Service API。

我喜欢让Singleton ServiceHelper绑定到(本地)服务的想法,但是我担心我对服务概念的理解不正确。

目前,我不了解如何将REST调用结果(在服务中异步完成)报告给调用者活动。我还想知道我是否需要一个可处理所有REST请求(具有不同返回类型)的服务,或者是否需要针对每个REST请求的专用服务。

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

请让我知道!

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

提前致谢。

克劳斯

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


1
Claszen,您是否对所有请求的单一服务和对每个请求的专用服务有任何看法?如果可以,请分享。在我的情况下,我的应用程序中有很多REST请求[大约20个]。我已经看过上述Google I / O中的宝贵会议。我的问题是,哪种方法更好。要让单个服务处理单个服务中的所有请求?还是为每个请求提供专门服务?我有一些请求应按顺序触发,其中一些请求可以同时触发。有什么建议么 ?

@ user778869我终于为每个(“顶级”)REST资源(例如“ company”,“ customer”)使用了一个IntentService和ResultReceiver。我发现这是一种“自然”的结构,效果很好。它可能会产生一些代码重复,但如果在一个服务中全部完成,则会避免过多使用控制结构。
FrVaBe 2011年

这对于学习Android REST客户端实施的人们可能非常有帮助。Dobjanschi的演示文稿转录为PDF:drive.google.com/file/d/0B2dn_3573C3RdlVpU2JBWXdSb3c/…–
Kay Zed

Answers:


50

概观

编辑:

任何感兴趣的人还可以考虑看看RESTful android,这可能会让您对此有更好的了解。

我从尝试实现Dobjanschi模型的经验中学到的是,并非所有事情都是一成不变的,他只是为您提供了可能会因应用程序而异的概述,但公式为:

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

某些应用程序上的模型可能与要求有所不同,有些可能不需要SyncAdapter帐户,其他可能使用C2DM,我最近使用的模型可能会帮助某人:


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

它将允许您使用SyncAdapter同步数据。在创建自己的SyncAdapter上已对此进行了讨论

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

这种抽象使您不仅可以访问数据库,而且可以使用ServiceHelper来执行REST调用,因为它具有REST Arch的一对一映射方法。

内容提供商| REST方法

查询----------------> GET

插入----------------> PUT

更新----------------> POST

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

ServiceHelper分层

这个家伙基本上会使用从ContentProvider传递的参数来启动执行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,这有什么用?请记住,服务是在后台运行事物的好方法。

还要实现BroadCastReceiver,以便当服务完成其工作时,通知我的Activity已注册此Broadcast并再次重新查询。我相信这不是Virgill会议的最后一步,但是我敢肯定这是一个不错的方法。

RESTMethod类

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

如果需要身份验证,则可以从AccountManager请求。如果由于身份验证而导致服务调用失败,则可以使身份验证无效并重新身份验证以获取新的令牌。

最终,无论我基于匹配器创建处理器并传递响应,RESTMethod都可以为我提供XML或JSON。

处理器

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

示例应用程序?当然!

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


感谢您的回答。最后,我为每个(“顶层”)REST资源(例如“ company”,“ customer”)使用了一个IntentService和ResultReceiver。Dobjanschi模型对我来说太重了。
FrVaBe 2011年

b使用IntentService和ResultReseiver,您可能使用的是第一个描述的场景,即服务驱动模型,尽管他使用Binder而不是ResultReceiver进行通信,但这很好,因为我说的不是一成不变的!
Necronet

前一段时间,我问了这个问题,然后找到了适合我的解决方案。我没有机会检查所有对示例应用程序的引用-但是,由于这是最新更新的答案,因此我会接受。尽管如此,我还是建议您检查所有其他答案。
FrVaBe

优秀的建议,检查所有答案,所有这些都有很多不错的资源和想法!就像Je​​remy的《 Android编程》一书Yoni的内容一样。
Necronet

@Necronet嗨,您偶然发现了您有前途的示例应用程序-但是,我在构建它时遇到了麻烦。您介意告诉我们必须针对哪个版本的ActionBarSherlock进行构建(似乎在使用最新的ABS 4.1时无法正常工作)?另外,从您的帖子中,我并没有真正找到您想要的Dobjanschi模型的模式(A,B或C)(我知道,您最终可能会有一些变化,但我想您主要关注的是其中一种模式-我想模式B?)谢谢!
vaiomike 2012年

17

编程Android有一整章专门介绍Virgil的Google I / O演讲中的“选项B:使用ContentProvider API”(第13章,探索内容提供者)。

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

在本章中,我们将通过第二个Finch视频示例详细探讨第二种模式。该策略将为您的应用程序带来许多重要的好处。由于这种方法将网络操作集成到Android MVC中的优雅方式,我们给它起了绰号“网络MVC”。

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

强烈推荐。

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


11

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

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


感谢您分享这个可能有用的链接(暂时没有机会深入了解)
FrVaBe 2012年

这看起来像一个解决方案。谢谢 !
文森特·坎廷

7

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

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

  • 异步执行(在后台AndroidService中)网络请求,这些请求将返回POJO(例如:REST请求)
  • 缓存结果(在Json,Xml,平面文本文件或二进制文件中)
  • 如果网络请求仍然有效,则将网络请求的结果通知您的活动(或任何其他上下文)
  • 如果活动不再存在,则不会将结果通知您
  • 在其UI线程上通知您的活动
  • 使用简单但健壮的异常处理模型
  • 支持多个ContentService来聚合不同的Web服务结果
  • 支持请求执行的多线程
  • 是强类型的!
  • 是开源的;)
  • 经过测试

我们实际上是在寻求社区的反馈。


4

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

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/

注意RestAdapter从Retrofit获得的适配器不是从BaseAdapter您派生的,应该以某种方式对此进行包装,例如SO问题 为什么在ListFragment内调用setListAdapter之后,我的ListView为空?


您能发布一个完整的示例来调用诸如api.icndb.com/jokes/random之
exequielc



By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.