即使这个帖子已经接受了答案,随意提出其他想法,你也可以使用或喜欢
我遇到过这些文章:
宁静的API服务
适用于Android的Java REST客户端API
这引导我看到关于REST客户端应用程序的Google I/O 2010视频
http://www.youtube.com/watch?v=xHXn3Kg2IQE&feature=player_embedded
从现在开始,我一直在我的Application控制器类中创建REST组件作为静态组件.
从现在开始,我认为,我应该改变模式.有人指出,Google IOSched应用程序是如何在Android上编写REST客户端的绝佳示例.有人说这种方式过于复杂.
那么,任何人都可以告诉我们什么是最佳做法?简而言之.
IOSched应用程序对于样本用例来说太复杂了.
这是2017年.只需使用Retrofit.几乎没有理由使用其他任何东西.
在编辑时,原始答案超过一年半.尽管原始答案中提出的概念仍然存在,正如其他答案所指出的那样,现在有些库可以让您更轻松地完成这项任务.更重要的是,其中一些库可以为您处理设备配置更改.
原始答案保留在下面以供参考.但是,请花时间检查Android的一些Rest客户端库,看看它们是否适合您的用例.以下是我评估过的一些库的列表.它绝不是一个详尽的清单.
排球(这是来自谷歌)
RESTDroid
RoboSpice
改造
介绍我在Android上使用REST客户端的方法.我并不认为这是最好的:)但是,请注意,这是我根据我的要求提出的.如果您的用例需要,您可能需要拥有更多层/添加更多复杂性.例如,我根本没有本地存储空间; 因为我的应用程序可以容忍丢失一些REST响应.
我的方法只使用了AsyncTask
s.在我的情况下,我从我的Activity
实例"调用"这些任务; 但要完全考虑屏幕旋转等情况,您可以选择从一个Service
或那样的电话中调用它们.
我有意识地选择我的REST客户端作为API.这意味着,使用我的REST客户端的应用程序甚至不需要知道实际的REST URL和使用的数据格式.
客户端有2层:
顶层:此层的目的是提供镜像REST API功能的方法.例如,您可以使用一个与REST API中的每个URL对应的Java方法(甚至两个 - 一个用于GET,一个用于POST).
这是REST客户端API的入口点.这是应用程序正常使用的图层.它可能是一个单身人士,但不一定.
REST调用的响应由此层解析为POJO并返回给应用程序.
这是较低级别的AsyncTask
层,它使用HTTP客户端方法实际出去并进行REST调用.
另外,我选择使用Callback机制将AsyncTask
s 的结果传回应用程序.
足够的文字.我们现在看一些代码.让我们假设一个REST API URL - http://myhypotheticalapi.com/user/profile
顶层可能如下所示:
/** * Entry point into the API. */ public class HypotheticalApi{ public static HypotheticalApi getInstance(){ //Choose an appropriate creation strategy. } /** * Request a User Profile from the REST server. * @param userName The user name for which the profile is to be requested. * @param callback Callback to execute when the profile is available. */ public void getUserProfile(String userName, final GetResponseCallback callback){ String restUrl = Utils.constructRestUrlForProfile(userName); new GetTask(restUrl, new RestTaskCallback (){ @Override public void onTaskComplete(String response){ Profile profile = Utils.parseResponseAsProfile(response); callback.onDataReceived(profile); } }).execute(); } /** * Submit a user profile to the server. * @param profile The profile to submit * @param callback The callback to execute when submission status is available. */ public void postUserProfile(Profile profile, final PostCallback callback){ String restUrl = Utils.constructRestUrlForProfile(profile); String requestBody = Utils.serializeProfileAsString(profile); new PostTask(restUrl, requestBody, new RestTaskCallback(){ public void onTaskComplete(String response){ callback.onPostSuccess(); } }).execute(); } } /** * Class definition for a callback to be invoked when the response data for the * GET call is available. */ public abstract class GetResponseCallback{ /** * Called when the response data for the REST call is ready.
* This method is guaranteed to execute on the UI thread. * * @param profile The {@code Profile} that was received from the server. */ abstract void onDataReceived(Profile profile); /* * Additional methods like onPreGet() or onFailure() can be added with default implementations. * This is why this has been made and abstract class rather than Interface. */ } /** * * Class definition for a callback to be invoked when the response for the data * submission is available. * */ public abstract class PostCallback{ /** * Called when a POST success response is received.
* This method is guaranteed to execute on the UI thread. */ public abstract void onPostSuccess(); }
请注意,应用程序不直接使用REST API返回的JSON或XML(或任何其他格式).相反,应用程序只看到bean Profile
.
然后,下层(AsyncTask层)可能如下所示:
/** * An AsyncTask implementation for performing GETs on the Hypothetical REST APIs. */ public class GetTask extends AsyncTask{ private String mRestUrl; private RestTaskCallback mCallback; /** * Creates a new instance of GetTask with the specified URL and callback. * * @param restUrl The URL for the REST API. * @param callback The callback to be invoked when the HTTP request * completes. * */ public GetTask(String restUrl, RestTaskCallback callback){ this.mRestUrl = restUrl; this.mCallback = callback; } @Override protected String doInBackground(String... params) { String response = null; //Use HTTP Client APIs to make the call. //Return the HTTP Response body here. return response; } @Override protected void onPostExecute(String result) { mCallback.onTaskComplete(result); super.onPostExecute(result); } } /** * An AsyncTask implementation for performing POSTs on the Hypothetical REST APIs. */ public class PostTask extends AsyncTask { private String mRestUrl; private RestTaskCallback mCallback; private String mRequestBody; /** * Creates a new instance of PostTask with the specified URL, callback, and * request body. * * @param restUrl The URL for the REST API. * @param callback The callback to be invoked when the HTTP request * completes. * @param requestBody The body of the POST request. * */ public PostTask(String restUrl, String requestBody, RestTaskCallback callback){ this.mRestUrl = restUrl; this.mRequestBody = requestBody; this.mCallback = callback; } @Override protected String doInBackground(String... arg0) { //Use HTTP client API's to do the POST //Return response. } @Override protected void onPostExecute(String result) { mCallback.onTaskComplete(result); super.onPostExecute(result); } } /** * Class definition for a callback to be invoked when the HTTP request * representing the REST API Call completes. */ public abstract class RestTaskCallback{ /** * Called when the HTTP request completes. * * @param result The result of the HTTP request. */ public abstract void onTaskComplete(String result); }
以下是应用可能如何使用API(在Activity
或中Service
):
HypotheticalApi myApi = HypotheticalApi.getInstance(); myApi.getUserProfile("techie.curious", new GetResponseCallback() { @Override void onDataReceived(Profile profile) { //Use the profile to display it on screen, etc. } }); Profile newProfile = new Profile(); myApi.postUserProfile(newProfile, new PostCallback() { @Override public void onPostSuccess() { //Display Success } });
我希望这些评论足以解释设计; 但我很乐意提供更多信息.
由Virgil Dobjanschi开发的"开发Android REST客户端应用程序"引发了很多讨论,因为在会话期间没有提供源代码或之后提供了源代码.
我知道的唯一参考实现(如果您了解更多,请发表评论)可在Datadroid上获得(Google IO会话在/ presentation下提及).它是一个可以在您自己的应用程序中使用的库.
第二个链接要求提供"最佳"REST框架,该框架在stackoverflow上进行了大量讨论.对我来说,应用程序的大小很重要,其次是实现的性能.
通常我使用普通的org.json实现,它是API级别1以来的Android的一部分,因此不会增加应用程序的大小.
对我来说非常有趣的是在评论中发现JSON解析器性能的信息:从Android 3.0 Honeycomb开始,GSON的流解析器包含在android.util.JsonReader中.不幸的是,评论不再可用.
Spring Android(我有时使用)支持Jackson和GSON.所述弹簧的Android RestTemplate Module文档指向一个示例应用.
因此,我坚持使用org.json或GSON来处理更复杂的场景.对于org.json实现的体系结构,我使用的是表示服务器用例的静态类(例如findPerson,getPerson).我从服务中调用此功能并使用实用程序类,这些类正在执行映射(特定于项目)和网络IO(我自己的REST模板用于纯GET或POST).我尽量避免使用反射.
永远不要使用AsynTask来执行网络请求或任何需要持久化的请求.异步任务与您的活动密切相关,如果用户在重新创建应用程序后更改了屏幕方向,则AsyncTask将停止.
我建议你使用Intent Service和ResultReceiver的服务模式.看看RESTDroid.它是一个库,允许您异步执行任何类型的REST请求,并通过请求监听器实现Virgil Dobjanschi的服务模式通知您的UI.