Android REST 客户端,示例? [英] Android REST client, Sample?

查看:38
本文介绍了Android REST 客户端,示例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

即使此线程已接受答案,也可以随意提出其他想法,您确实使用或喜欢

我见过这些文章:

这让我看到了这个关于 REST 客户端应用程序的 Google I/O 2010 视频

And that lead me to this Google I/O 2010 video about REST client applications

从现在开始,我一直在我的应用程序控制器类中创建 REST 组件作为静态组件.

Since now, I've been creating REST component as static component in my Application controller class.

从现在开始,我想,我应该改变模式.有人指出Google IOSched 应用程序是如何在 Android 上编写 REST 客户端的绝佳示例.其他人表示这种方式过于复杂.

From now, I think, I should change the pattern. Somebody pointed out that Google IOSched application is great sample of how to write REST clients on Android. Somebody else told that this ways is too overcomplicated.

那么,有人可以告诉我们什么是最佳实践吗?简而言之.
IOSched 应用程序对于示例用例来说太复杂了.

So, can anybody please show us what is the best practice? In short and simple way.
The IOSched application is too complex for sample use-case.

推荐答案

EDIT 2(2017 年 10 月):

现在是 2017 年.只需使用 Retrofit.几乎没有理由使用其他任何东西.

EDIT 2 (October 2017):

It is 2017. Just use Retrofit. There is almost no reason to use anything else.

原始答案在进行此编辑时已有一年半多的历史.尽管原始答案中提出的概念仍然成立,但正如其他答案所指出的那样,现在有一些库可以让您更轻松地完成这项任务.更重要的是,其中一些库会为您处理设备配置更改.

The original answer is more than a year and a half old at the time of this edit. Although the concepts presented in original answer still hold, as other answers point out, there are now libraries out there that make this task easier for you. More importantly, some of these libraries handle device configuration changes for you.

以下保留原答案以供参考.但也请花点时间检查一些适用于 Android 的 Rest 客户端库,看看它们是否适合您的用例.以下是我评估过的一些库的列表.它绝不是一份详尽的清单.

The original answer is retained below for reference. But please also take the time to examine some of the Rest client libraries for Android to see if they fit your use cases. The following is a list of some of the libraries I've evaluated. It is by no means intended to be an exhaustive list.

  • Volley (this is from Google)
  • RESTDroid
  • RoboSpice
  • Retrofit

介绍我在 Android 上使用 REST 客户端的方法.我并不声称它是最好的 :) 另外,请注意,这是我根据我的要求提出的.如果您的用例需要,您可能需要更多层/增加更多复杂性.例如,我根本没有本地存储;因为我的应用可以容忍丢失一些 REST 响应.

Presenting my approach to having REST clients on Android. I do not claim it is the best though :) Also, note that this is what I came up with in response to my requirement. You might need to have more layers/add more complexity if your use case demands it. For example, I do not have local storage at all; because my app can tolerate loss of a few REST responses.

我的方法在幕后只使用 AsyncTask .就我而言,我打电话"这些来自我的 Activity 实例的任务;但要充分考虑屏幕旋转等情况,您可以选择从 Service 等调用它们.

My approach uses just AsyncTasks under the covers. In my case, I "call" these Tasks from my Activity instance; but to fully account for cases like screen rotation, you might choose to call them from a Service or such.

我有意识地选择我的 REST 客户端本身作为 API.这意味着,使用我的 REST 客户端的应用程序甚至不需要知道实际的 REST URL 和使用的数据格式.

I consciously chose my REST client itself to be an API. This means, that the app which uses my REST client need not even be aware of the actual REST URL's and the data format used.

客户端将有 2 层:

  1. 顶层:该层的目的是提供反映 REST API 功能的方法.例如,您可以有一个与 REST API 中的每个 URL 对应的 Java 方法(或者甚至两个 - 一个用于 GET,一个用于 POST).
    这是 REST 客户端 API 的入口点.这是应用程序通常会使用的层.它可能是一个单身人士,但不一定.
    REST 调用的响应被这一层解析成一个 POJO 并返回给应用程序.

  1. Top layer: The purpose of this layer is to provide methods which mirror the functionality of the REST API. For example, you could have one Java method corresponding to every URL in your REST API (or even two - one for GETs and one for POSTs).
    This is the entry point into the REST client API. This is the layer the app would use normally. It could be a singleton, but not necessarily.
    The response of the REST call is parsed by this layer into a POJO and returned to the app.

这是较低级别的 AsyncTask 层,它使用 HTTP 客户端方法实际出去并进行 REST 调用.

This is the lower level AsyncTask layer, which uses HTTP client methods to actually go out and make that REST call.

此外,我选择使用回调机制将 AsyncTask 的结果传回应用程序.

In addition, I chose to use a Callback mechanism to communicate the result of the AsyncTasks back to the app.

足够的文字.现在让我们看一些代码.让我们假设一个 REST API URL - http://myhypotheticalapi.com/user/profile

Enough of text. Let's see some code now. Lets take a hypothetical 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.

Note that the app doesn't use the JSON or XML (or whatever other format) returned by the REST API directly. Instead, the app only sees the bean Profile.

那么,下层(AsyncTask 层)可能看起来像这样:

Then, the lower layer (AsyncTask layer) might look like this:

/**
 * 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 的方式(在 ActivityService 中):

Here's how an app might use the API (in an Activity or 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
            }
        });

我希望评论足以解释设计;但我很乐意提供更多信息.

I hope the comments are sufficient to explain the design; but I'd be glad to provide more info.

这篇关于Android REST 客户端,示例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆