适用于Android的REST API客户端库
我们正在构build一个基于位置的消息应用程序,使用Parse.com作为后端(Parse.com类似于Urban Airship / PubNub等),我们现在想切换到我们自己的后端,以便更好地控制。 为此,我们已经构build了一个基于node.js的后端,通过REST API公开了function
为了使用这个API,我们要构build一个Android库(类似于Parse.com的Android SDK ),它抽象所有的HTTP Requests / Response或者REST API调用,并为getUsers(),sendMessage()等各种操作提供直接的函数
在Android中实现REST API客户端的方法:
- 使用IntentService + ResultReceiver
- 服务
- 的AsyncTask
- 使用装载机
现在,考虑到我们要构build一个Android库,并且在用户与应用程序进行交互时可能会同时发生REST API调用,哪种方法最适合继续使用? 我也接受其他build议/build议。
更新 :我们首先使用IntentService + ResultReceiverbuild立我们自己的库,它工作正常。 但是我们后来偶然发现了Android Async Http 。 用它。 这很棒!
我所见过的基于Google IO Pro Tips 2010的最佳实践是RoboSpice库,它基于REST,非常巧妙地与Activity生命周期一起工作,不会泄漏内存。
图书馆的快速信息图在这里
- 装载机是为数据库devise的,而不是REST,它们在活动重置时重置,这意味着你丢失了数据。
- asynchronous任务,只是没有。
- 意向服务+结果接收器基本上RoboSpice是如何工作的,所以如果你正在构build自己的lib,我会采取这种方法!
- 服务也很好,与IntentService方法类似,但是IntentService在这个例子中更好一些。
Service
方法可能更好一些, 看一下他们使用ExecutorService
的robospice服务 ,它在用完Requests
时候终止Service
,这比Java更具体的Java并发。 需要注意的是,服务在处理请求的同时运行,如果没有剩余的话就终止它的自我。
使用ExecutorService
或任何types的线程池的优点是可以定义一次可以运行多less个请求。 除非你有一个非常快速的连接2-4是最有我会build议。
可能是这个类可以帮助: –
/*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(); }
我已经使用Retrofit ,它是一个非常好的库,它提供了一个简单的结构来pipe理端点和parsing数据/集合/对象。
该文档已经足够完整,可以轻松编写代码。
CQFD>去吧
你也可以使用RESTDroid 。 这与RoboSpice非常相似,但使用起来更简单(虽然function也不那么强大)。
如果你为RESTDroid创build一个Parse.com模块,不要犹豫,把它添加到GitHub!
如果我可以再添加一个,我最近开始编写一个很好的库来实现引擎(在iOS中使用MKNetworkKit)和命令与Android的REST API进行通信。 可能对试图访问REST API的任何人都有帮助。 https://github.com/m2d2/MDBaseAndroidLibraries
你也可以尝试Android Annotations和rest-spring插件来自动执行这些任务。
他们在Android的弹簧框架上使用包装,并提供一个真正的好方法来处理restapis 。
例子:
用@Background注释replaceAsyncTask – > doInBackground():
@Background protected void backgroundWork(){ // do something in background }
用@UiThreadreplacerunOnUiThread,onPostExecute()
@UiThread protected void uiWork(){ // do something on UI Thread }
Rest API的
创buildrest客户端:
@Rest(rootUrl = "http://company.com/ajax/services", converters = { MappingJackson2HttpMessageConverter.class }) public interface MyRestClient { @Get("/events") EventList getEvents(); }
使用rest客户端:
@RestClient MyRestClient myRestClient; public void showAllEvents(){ EventList list = myRestClient.getEvents(); // do something with this list }