Pretty much every mobile app you write is going sooner or later to invoke a web service and with REST dominating the place, it’s a good bet to start looking at the existing Android REST APIs in order to make your life easier.
I was investigating several of them but my attention got caught by two in particular. However do not take that as a recommendation, I just want to report my own experience here.
I - The Android Asynchronous Http Client API
Here is how its author defines that API:
An asynchronous callback-based Http client for Android built on top of Apache’s HttpClient libraries. All requests are made outside of your app’s main UI thread, but any callback logic will be executed on the same thread as the callback was created using Android’s Handler message passing.
A taste of its interesting capabilities includes making asynchronous HTTP requests managed from a threadpool, multipart file uploads, smart request retries, built-in gzip decompression & json parsing, and more…
All that for a tiny size overhead to your application: only 25kb for everything!
I found it well documented and pretty straightforward to use. Below are two examples that illustrate invoking a REST service. I choose for that to retrieve the 50 latest post of our C&M blog using the Typepad REST/Json API:
// simple test of AsyncHttpClient API
void TestAsyncClientSimple()
{
Clear();
// blogId of our Cloud&Mobile blog
String blogId = "6a0167607c2431970b0168ebc3adf1970c";
// REST request that grabs the 50 latest posts
String request =
"http://api.typepad.com/blogs/" + blogId +
"/post-assets/@published/@recent.js";
// creates simple async client
AsyncHttpClient client = new AsyncHttpClient();
// starts indeterminate progress dialog
final ProgressDialog dlg = ProgressDialog.show(
this,
"Retrieving REST data",
"Please Wait...", true);
// performs GET request
client.get(request, new AsyncHttpResponseHandler()
{
@Override
public void onSuccess(String response)
{
dlg.dismiss();
// parses the response into a blog post collection
List<AdnBlogPost> postCollection =
AdnBlogPost.getBlogPostCollection(response);
// displays in our simple UI
for(AdnBlogPost post : postCollection)
Print(" - " + Html.fromHtml(post.title) + "\n" +
" By " + post.author.displayName + "\n\n");
}
@Override
public void onFailure(Throwable ex, String msg)
{
Print(" Request failed: " + msg);
dlg.dismiss();
}
});
}
// A more OO approach to perform
// the same REST request
class AdnRestClient
{
private String _baseUrl;
private AsyncHttpClient _client;
public AdnRestClient(String baseUrl)
{
_baseUrl = baseUrl;
_client = new AsyncHttpClient();
}
public void get(
String url,
RequestParams params,
AsyncHttpResponseHandler responseHandler)
{
_client.get(getAbsoluteUrl(url), params, responseHandler);
}
public void post(
String url,
RequestParams params,
AsyncHttpResponseHandler responseHandler)
{
_client.post(getAbsoluteUrl(url), params, responseHandler);
}
private String getAbsoluteUrl(String relativeUrl)
{
return _baseUrl + relativeUrl;
}
}
// test method for AdnRestClient
void TestAsyncClient()
{
Clear();
String blogId = "6a0167607c2431970b0168ebc3adf1970c";
String request = blogId +
"/post-assets/@published/@recent.js";
AdnRestClient client =
new AdnRestClient("http://api.typepad.com/blogs/");
final ProgressDialog dlg = ProgressDialog.show(
this,
"Retrieving REST data",
"Please Wait...", true);
AsyncHttpResponseHandler responseHandler =
new AsyncHttpResponseHandler()
{
@Override
public void onSuccess(String response)
{
dlg.dismiss();
List<AdnBlogPost> postCollection =
AdnBlogPost.getBlogPostCollection(response);
for(AdnBlogPost post : postCollection)
Print(" - " + Html.fromHtml(post.title) + "\n" +
" By " + post.author.displayName + "\n\n");
}
@Override
public void onFailure(Throwable ex, String msg)
{
Print(" Request failed: " + msg);
dlg.dismiss();
}
};
client.get(request, null, responseHandler);
}
--
The result of my query looks like below in my UI:
-
--
II - The Volley API
Volley is a networking API that was introduced at the Google I/O 2013 conference. You can find the recording here.
Volley automatically schedule all network requests. It means that the framework will be taking care of all the network requests your app executes for fetching response or image from web. It provides transparent disk and memory caching, powerful customization abilities and also debugging and tracing tools.
I created two basic examples below: the first one is similar to the previous examples retrieving the typepad recent posts using a simple http string request and parsing the result with custom logic. The second one illustrates the Volley built-in JsonObjectRequest.
// Test an http request with Volley API
void TestVolleyRequest()
{
Clear();
// creates new request queue, the request will be
// handled by the framework once added to the queue
RequestQueue queue = Volley.newRequestQueue(this);
String blogId = "6a0167607c2431970b0168ebc3adf1970c";
String url =
"http://api.typepad.com/blogs/" + blogId +
"/post-assets/@published/@recent.js";
final ProgressDialog dlg = ProgressDialog.show(
this,
"Retrieving REST data",
"Please Wait...", true);
StringRequest request =
new StringRequest(Request.Method.GET, url,
new Listener<String>()
{
@Override
public void onResponse(String response)
{
dlg.dismiss();
List<AdnBlogPost> postCollection =
AdnBlogPost.getBlogPostCollection(response);
for(AdnBlogPost post : postCollection)
Print(" - " + Html.fromHtml(post.title) + "\n" +
" By " + post.author.displayName + "\n\n");
}
},
new ErrorListener()
{
@Override
public void onErrorResponse(VolleyError error)
{
Print(" Request failed: " + error.toString());
dlg.dismiss();
}
});
// allows to define request timeout
request.setRetryPolicy(
new DefaultRetryPolicy(20 * 1000, 1, 1.0f));
// add our request to the queue,
// no invocation needed
queue.add(request);
}
// test REST request with json reply using Volley API
void TestVolleyJsonRequest()
{
Clear();
RequestQueue queue = Volley.newRequestQueue(this);
// Check http://www.jsontest.com for details about
// json test services
String url = "http://date.jsontest.com";
final ProgressDialog dlg = ProgressDialog.show(
this,
"Retrieving REST data",
"Please Wait...", true);
JsonObjectRequest request =
new JsonObjectRequest(Request.Method.GET, url, null,
new Listener<JSONObject>()
{
@Override
public void onResponse(JSONObject response)
{
dlg.dismiss();
// Example response
// {
// "date":"09-25-2013",
// "milliseconds_since_epoch":1380120730723,
// "time":"02:52:10 PM"
// }
try
{
Print(" - Date: " + response.getString("date") + "\n");
Print(" - Time: " + response.getString("time"));
}
catch (JSONException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
},
new ErrorListener()
{
@Override
public void onErrorResponse(VolleyError error)
{
Print(" Request failed: " + error.toString());
dlg.dismiss();
}
});
request.setRetryPolicy(
new DefaultRetryPolicy(20 * 1000, 1, 1.0f));
queue.add(request);
}
-
More advanced examples using Volley API are available here.
-
III – Other Android Networking APIs
-
There are plenty other networking and REST APIs for Android out there. I didn’t have time to check them all in detail, but here is another set of interesting ones:
Seems powerful but more complex to use. It provides built-in support not only for networking but to store and manage your data.
I found it less straightforward to use for my simple test cases
I hope you enjoyed and wish you good luck in your quest through the web services jungle!
The complete source code of my project can be downloaded below:
Hi Philippe,
Thank you for this very useful overview!
Cheers, Jeremy.
Posted by: Jeremy Tammik | 09/26/2013 at 10:53 PM
Thanks Jeremy!
Posted by: Philippe | 09/27/2013 at 02:27 AM