How to call a RESTful web service from Android?
This is an sample restclient class
public class RestClient{ public enum RequestMethod { GET, POST } public int responseCode=0; public String message; public String response; public void Execute(RequestMethod method,String url,ArrayList<NameValuePair> headers,ArrayList<NameValuePair> params) throws Exception { switch (method) { case GET: { // add parameters String combinedParams = ""; if (params!=null) { combinedParams += "?"; for (NameValuePair p : params) { String paramString = p.getName() + "=" + URLEncoder.encode(p.getValue(),"UTF-8"); if (combinedParams.length() > 1) combinedParams += "&" + paramString; else combinedParams += paramString; } } HttpGet request = new HttpGet(url + combinedParams); // add headers if (headers!=null) { headers=addCommonHeaderField(headers); for (NameValuePair h : headers) request.addHeader(h.getName(), h.getValue()); } executeRequest(request, url); break; } case POST: { HttpPost request = new HttpPost(url); // add headers if (headers!=null) { headers=addCommonHeaderField(headers); for (NameValuePair h : headers) request.addHeader(h.getName(), h.getValue()); } if (params!=null) request.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8)); executeRequest(request, url); break; } } } private ArrayList<NameValuePair> addCommonHeaderField(ArrayList<NameValuePair> _header) { _header.add(new BasicNameValuePair("Content-Type","application/x-www-form-urlencoded")); return _header; } private void executeRequest(HttpUriRequest request, String url) { HttpClient client = new DefaultHttpClient(); HttpResponse httpResponse; try { httpResponse = client.execute(request); responseCode = httpResponse.getStatusLine().getStatusCode(); message = httpResponse.getStatusLine().getReasonPhrase(); HttpEntity entity = httpResponse.getEntity(); if (entity != null) { InputStream instream = entity.getContent(); response = convertStreamToString(instream); instream.close(); } } catch (Exception e) { } } private static String convertStreamToString(InputStream is) { BufferedReader reader = new BufferedReader(new InputStreamReader(is)); StringBuilder sb = new StringBuilder(); String line = null; try { while ((line = reader.readLine()) != null) { sb.append(line + "\n"); } is.close(); } catch (IOException e) { } return sb.toString(); }}
Recently discovered that a third party library - Square Retrofit can do the job very well.
Defining REST endpoint
public interface GitHubService { @GET("/users/{user}/repos") List<Repo> listRepos(@Path("user") String user,Callback<List<User>> cb);}
Getting the concrete service
RestAdapter restAdapter = new RestAdapter.Builder() .setEndpoint("https://api.github.com") .build();GitHubService service = restAdapter.create(GitHubService.class);
Calling the REST endpoint
List<Repo> repos = service.listRepos("octocat",new Callback<List<User>>() { @Override public void failure(final RetrofitError error) { android.util.Log.i("example", "Error, body: " + error.getBody().toString()); } @Override public void success(List<User> users, Response response) { // Do something with the List of Users object returned // you may populate your adapter here }});
The library handles the json serialization and deserailization for you. You may customize the serialization and deserialization too.
Gson gson = new GsonBuilder() .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) .registerTypeAdapter(Date.class, new DateTypeAdapter()) .create();RestAdapter restAdapter = new RestAdapter.Builder() .setEndpoint("https://api.github.com") .setConverter(new GsonConverter(gson)) .build();
Stop with whatever you were doing ! :)
Implement the RESTful client as a SERVICE and delegate the intensive network stuff to activity independent component: a SERVICE.
Watch this insightful videohttp://www.youtube.com/watch?v=xHXn3Kg2IQE where Virgil Dobjanschi is explaining his approach(es) to this challenge...