Android REST客户端,Sample?

时间:2011-11-25 10:46:19

标签: java android api rest

即使这个帖子已经接受了答案,随时提出其他想法,你也可以使用或喜欢


我见过这些文章:

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

从现在开始,我一直在我的Application控制器类中创建REST组件作为静态组件。

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

那么,任何人都可以告诉我们什么是最佳做法?简而言之 IOSched应​​用程序对于样本用例而言过于复杂。

7 个答案:

答案 0 :(得分:94)

编辑2(2017年10月):

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

编辑:

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

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


原始答案:

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

我的方法仅使用AsyncTask封面。就我而言,我从Activity实例“调用”这些任务;但要完全考虑屏幕旋转等情况,您可以选择从Service或类似地调用它们。

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

客户端有两层:

  1. 顶层:此层的目的是提供镜像REST API功能的方法。例如,您可以使用一个与REST API中的每个URL相对应的Java方法(甚至两个 - 一个用于GET,一个用于POST)。 这是REST客户端API的入口点。这是应用程序正常使用的图层。它可能是单身人士,但不一定 REST调用的响应由此层解析为POJO并返回给应用程序。

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

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

    足够的文字。我们现在看一些代码。让我们假设一个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​​(ActivityService中):

    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
                }
            });
    

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

答案 1 :(得分:11)

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

Datadroid提供了我知道的唯一参考实现(如果您了解更多,请发表评论)(Google IO会话在/ presentation下提及)。它是一个可以在您自己的应用程序中使用的库。

第二个链接要求提供“最佳”REST框架,该框架在stackoverflow上进行了大量讨论。对我来说,应用程序的大小很重要,其次是实现的性能。

  • 通常我使用普通的org.json实现,它是API级别1以来的Android的一部分,因此不会增加应用程序的大小。
  • 对我来说非常有趣的是评论中JSON parsers performance上的信息:从Android 3.0 Honeycomb开始,GSON的流解析器包含在android.util.JsonReader中。不幸的是,这些评论不再可用。
  • Spring Android(我有时使用)支持Jackson和GSON。 Spring Android RestTemplate Module documentation指向sample app

因此,我坚持使用org.json或GSON来处理更复杂的场景。对于org.json实现的体系结构,我使用的是表示服务器用例的静态类(例如findPerson,getPerson)。我从服务中调用此功能并使用实用程序类,这些类正在执行映射(特定于项目)和网络IO(我自己的REST模板用于纯GET或POST)。我尽量避免使用反射。

答案 2 :(得分:7)

永远不要使用AsynTask来执行网络请求或任何需要持久化的请求。 Async Task与您的活动密切相关,如果用户在重新创建应用程序后更改了屏幕方向,则AsyncTask将停止。

我建议您使用服务模式与Intent Service和ResultReceiver。看看RESTDroid。它是一个库,允许您异步执行任何类型的REST请求,并通过请求监听器实现Virgil Dobjanschi的服务模式来通知您的UI。

答案 3 :(得分:3)

还有另一个库具有更清晰的API和类型安全数据。 https://github.com/kodart/Httpzoid

这是一个简单的用法示例

Http http = HttpFactory.create(context);
http.post("http://example.com/users")
    .data(new User("John"))
    .execute();

或者更复杂的回调

Http http = HttpFactory.create(context);
http.post("http://example.com/users")
    .data(new User("John"))
    .handler(new ResponseHandler<Void>() {
        @Override
        public void success(Void ignore, HttpResponse response) {
        }

        @Override
        public void error(String message, HttpResponse response) {
        }

        @Override
        public void failure(NetworkError error) {
        }

        @Override
        public void complete() {
        }
    }).execute();

这是新鲜事,但看起来非常有希望。

答案 4 :(得分:1)

那里有很多图书馆,我正在使用这个:https://github.com/nerde/rest-resource。这是由我创建的,正如您在文档中看到的那样,它比其他方式更清晰,更简单。它并不专注于Android,但我正在使用它并且它运行良好。

它支持HTTP Basic Auth。它执行序列化和反序列化JSON对象的脏工作。您会喜欢它,特别是如果您的API是Rails之类的。

答案 5 :(得分:1)

免责声明:我参与了rest2mobile开源项目

作为REST客户端的另一种选择是使用rest2mobile

该方法略有不同,因为它使用具体的rest examples来生成REST服务的客户端代码。该代码使用本机java方法和POJO替换REST URL和JSON有效内容。它还自动处理服务器连接,异步调用和POJO到/从JSON转换。

请注意,此工具有不同的风格(cli,插件,android / ios / js支持),您可以使用android studio plugin直接在您的应用中生成API。

所有代码都可以在github here找到。

答案 6 :(得分:0)

我们已经为Android开源了我们的轻量级异步REST客户端库,如果您有最低要求并且不想自己处理多线程,则可能会发现它很有用-对于基本通信来说,这是非常好的,但对于完整通信来说,强大的REST客户端库。

它称为libRESTfulClient和can be found on GitHub