48

我们正在构建一个基于位置的消息应用程序,它使用 Parse.com 作为后端(Parse.com 类似于 Urban Airship/PubNub 等),我们现在希望切换到我们自己的后端以获得更好的控制。为此,我们构建了一个基于 node.js 的后端,其功能通过 REST API 公开

为了使用这个 API,我们想要构建一个 Android 库(类似于Parse.com 的 Android SDK),它抽象了所有 HTTP 请求/响应或 REST API 调用,并为 getUsers()、sendMessage() 等各种操作提供直接函数

在 Android 中实现 REST API 客户端的方法:

现在,考虑到我们想要构建一个 android 库,并且在用户与应用程序交互时可能会同时调用 REST API,哪种方法最好继续?我也愿意接受其他建议/建议。

更新:我们首先使用 IntentService + ResultReceiver 构建了我们自己的库,效果很好。但我们后来偶然发现了Android Async Http。用它。这很棒!

4

6 回答 6

43

我见过的基于 Google IO Pro Tips 2010 的最佳实现是 RoboSpice 库,它是基于 REST 的,并且非常巧妙地与 Activity 生命周期配合使用,不会泄漏内存。

图书馆的快速信息图在这里

  • 加载器是为数据库设计的,而不是 REST,它们在活动重置时重置,这意味着您丢失了数据。
  • 异步任务,只是没有。
  • Intent Service + Result 接收器基本上是 RoboSpice 的工作方式,所以如果您正在构建自己的库,我会采用这种方法!
  • Service 也不错,类似于 IntentService 方法,但是 IntentService 在这种情况下工作得更好一些。

Service方法可能更好,看看他们使用的 robospice 服务,当它用完时ExecutorService终止,这比 Android 特定的更多 Java 并发。需要注意的主要事情是,服务在处理请求时运行,然后在没有请求的情况下终止其自身。ServiceRequests

使用ExecutorService线程池或任何类型的线程池的优点是您可以定义一次可以运行多少个请求。除非你有一个非常快的连接 2-4 是我所建议的最多的。

于 2012-11-18T20:15:12.027 回答
9

我使用了Retrofit,它是一个非常好的库,它为管理端点和解析数据/集合/对象提供了一个简单的结构。

文档足够完整,可以轻松编写代码。

CQFD > 去吧

于 2014-12-08T21:37:39.570 回答
8

这门课可能会有所帮助:-

/*Copyright 2014 Bhavit Singh Sengar
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.*/

package com.infotech.zeus.util;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.json.JSONException;
import org.json.JSONObject;
import android.widget.Toast;

public class RestClient {


        JSONObject data = new JSONObject();
        String url;
        String headerName;
        String headerValue;

        public RestClient(String s){

            url = s;
        }


        public void addHeader(String name, String value){

            headerName = name;
            headerValue = value;

        }

        public void addParam(String key, String value){

            try {
                data.put(key, value);
            } catch (JSONException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }


        }

        public String executePost(){  // If you want to use post method to hit server

            HttpClient httpClient = new DefaultHttpClient();
            HttpPost httpPost = new HttpPost(url);
            httpPost.setHeader(headerName, headerValue);
            HttpResponse response = null;
            String result = null;
            try {
                StringEntity entity = new StringEntity(data.toString(), HTTP.UTF_8);
                httpPost.setEntity(entity);
                response = httpClient.execute(httpPost);
                HttpEntity entity1 = response.getEntity();
                result = EntityUtils.toString(entity1);
                return result;
                //Toast.makeText(MainPage.this, result, Toast.LENGTH_LONG).show();
            } catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (ClientProtocolException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return result;



        }

        public String executeGet(){ //If you want to use get method to hit server

            HttpClient httpClient = new DefaultHttpClient();
            HttpGet httpget = new HttpGet(url);
            String result = null;
            ResponseHandler<String> responseHandler = new BasicResponseHandler();
            try {
                result = httpClient.execute(httpget, responseHandler);
            } catch (ClientProtocolException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            return result;
        }
}

使用此类的简单示例:

RestClient client = new RestClient("http://www.example.com/demo.php");  //Write your url here
        client.addParam("Name", "Bhavit"); //Here I am adding key-value parameters
        client.addParam("Age", "23");

        client.addHeader("content-type", "application/json"); // Here I am specifying that the key-value pairs are sent in the JSON format

        try {
            String response = client.executePost(); // In case your server sends any response back, it will be saved in this response string.

        } catch (Exception e) {
            e.printStackTrace();
        }
于 2014-04-09T10:14:13.107 回答
4

您也可以使用RESTDroid。它与 RoboSpice 非常相似,但使用起来更简单(尽管功能也较弱。)

如果您为 RESTDroid 创建 Parse.com 模块,请不要犹豫,将其添加到 GitHub 上!

于 2013-02-13T20:05:09.553 回答
1

如果我可以再补充一点,我最近开始编写一个不错的库来实现引擎(在 iOS 中被 MKNetworkKit 使用)和命令来与 Android 的 REST API 进行通信。可能对任何尝试使用 REST API 的人有所帮助。https://github.com/m2d2/MDBaseAndroidLibraries

于 2013-02-04T03:06:16.023 回答
1

你也可以尝试使用带有rest-spring插件的Android Annotations来自动完成这些任务。

他们在spring 框架上为 android使用了一个包装器,并提供了一种处理rest apis的非常好的方法。

例子:

将 AsyncTask -> doInBackground() 替换为 @Background 注释:

@Background
protected void backgroundWork(){
    // do something in background
}

用 @UiThread 替换 runOnUiThread、onPostExecute()

@UiThread
protected void uiWork(){
    // do something on UI Thread
}

对于 Rest API

创建休息客户端:

@Rest(rootUrl = "http://company.com/ajax/services",
      converters = { MappingJackson2HttpMessageConverter.class })
public interface MyRestClient {

    @Get("/events")
    EventList getEvents();
}

使用休息客户端:

@RestClient
MyRestClient myRestClient;

public void showAllEvents(){
    EventList list = myRestClient.getEvents();
    // do something with this list

}
于 2016-05-06T08:56:13.883 回答