编辑2(2017年10月):
现在是2017年。只需使用翻新即可。几乎没有理由使用其他任何东西。
编辑:
进行此编辑时,原始答案已存在一年半以上。尽管原始答案中提出的概念仍然存在,但正如其他答案所指出的那样,现在有一些库可以使您轻松完成此任务。更重要的是,其中一些库可为您处理设备配置更改。
原始答案保留在下面以供参考。但也请花些时间检查一些适用于Android的Rest客户端库,以了解它们是否适合您的用例。以下是我评估过的一些库的列表。它绝不是详尽的清单。
原始答案:
介绍我在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调用。
另外,我选择使用回调机制将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. <br/>
* 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. <br/>
* 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<String, String, String>{
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<String, String, String>{
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
}
});
我希望这些评论足以说明设计;但我很乐意提供更多信息。