Android Rest Client, Sample

Android REST client, Sample?

EDIT 2 (October 2017):

It is 2017. Just use Retrofit. There is almost no reason to use anything else.

EDIT:

The original answer is more than a year and a half old at the time of this edit. Although the concepts presented in original answer still hold, as other answers point out, there are now libraries out there that make this task easier for you. More importantly, some of these libraries handle device configuration changes for you.

The original answer is retained below for reference. But please also take the time to examine some of the Rest client libraries for Android to see if they fit your use cases. The following is a list of some of the libraries I've evaluated. It is by no means intended to be an exhaustive list.

  • Volley (this is from Google)
  • RESTDroid
  • RoboSpice
  • Retrofit


Original Answer:

Presenting my approach to having REST clients on Android. I do not claim it is the best though :) Also, note that this is what I came up with in response to my requirement. You might need to have more layers/add more complexity if your use case demands it. For example, I do not have local storage at all; because my app can tolerate loss of a few REST responses.

My approach uses just AsyncTasks under the covers. In my case, I "call" these Tasks from my Activity instance; but to fully account for cases like screen rotation, you might choose to call them from a Service or such.

I consciously chose my REST client itself to be an API. This means, that the app which uses my REST client need not even be aware of the actual REST URL's and the data format used.

The client would have 2 layers:

  1. Top layer: The purpose of this layer is to provide methods which mirror the functionality of the REST API. For example, you could have one Java method corresponding to every URL in your REST API (or even two - one for GETs and one for POSTs).

    This is the entry point into the REST client API. This is the layer the app would use normally. It could be a singleton, but not necessarily.

    The response of the REST call is parsed by this layer into a POJO and returned to the app.

  2. This is the lower level AsyncTask layer, which uses HTTP client methods to actually go out and make that REST call.

In addition, I chose to use a Callback mechanism to communicate the result of the AsyncTasks back to the app.

Enough of text. Let's see some code now. Lets take a hypothetical REST API URL - http://myhypotheticalapi.com/user/profile

The top layer might look like this:

   /**
* 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();

}

Note that the app doesn't use the JSON or XML (or whatever other format) returned by the REST API directly. Instead, the app only sees the bean Profile.

Then, the lower layer (AsyncTask layer) might look like this:

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

Here's how an app might use the API (in an Activity or Service):

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

I hope the comments are sufficient to explain the design; but I'd be glad to provide more info.

Need sample Android REST Client project which implements Virgil Dobjanschi REST implementation pattern

OverView

Edit:

Anyone interest also consider taking a look at RESTful android this might give you a better look about it.

What i learned from the experience on trying to implement the Dobjanschi Model, is that not everything is written in stone and he only give you the overview of what to do this might changed from app to app but the formula is:

Follow this ideas + Add your own = Happy Android application

The model on some apps may vary from requirement some might not need the Account for the SyncAdapter other might use C2DM, this one that i worked recently might help someone:


Create an application that have Account and AccountManager

It will allow you to use the SyncAdapter to synchronized your data. This have been discussed on Create your own SyncAdapter

Create a ContentProvider (if it suits your needs)

This abstraction allows you to not only access the database but goes to the ServiceHelper to execute REST calls as it has one-per-one Mapping method with the REST Arch.

Content Provider | REST Method

query ----------------> GET

insert ----------------> PUT

update ----------------> POST

delete ----------------> DELETE

ServiceHelper Layering

This guy will basicly start (a) service(s) that execute a Http(not necessarily the protocol but it's the most common) REST method with the parameters that you passed from the ContentProvider. I passed the match integer that is gotten from the UriMatcher on the content Provider so i know what REST resource to access, i.e.

class ServiceHelper{

public static void execute(Context context,int match,String parameters){
//find the service resource (/path/to/remote/service with the match
//start service with parameters
}

}

The service

Gets executed (I use IntentService most of the time) and it goes to the RESTMethod with the params passed from the helper, what is it good for? well remember Service are good to run things in background.

Also implement a BroadCastReceiver so when the service is done with its work notify my Activity that registered this Broadcast and requery again. I believe this last step is not on Virgill Conference but I'm pretty sure is a good way to go.

RESTMethod class

Takes the parameters, the WS resource(http://myservice.com/service/path) adds the parameters,prepared everything, execute the call, and save the response.

If the authtoken is needed you can requested from the AccountManager
If the calling of the service failed because authentication, you can invalidate the authtoken and reauth to get a new token.

Finally the RESTMethod gives me either a XML or JSON no matter i create a processor based on the matcher and pass the response.

The processor

It's in charged of parsing the response and insert it locally.

A Sample Application? Of course!

Also if you are interesting on a test application you look at Eli-G, it might not be the best example but it follow the Service REST approach, it is built with ServiceHelper, Processor, ContentProvider, Loader, and Broadcast.

Android REST Client: best solution?

All you need is here.
https://square.github.io/retrofit/
Its easy to use and you almost dont have to care about json deserialization

how to build REST client in android using HttpUrlConnection

This is sample code for calling an Http GET using HttpUrlConnection in Android.

  URL url;
HttpURLConnection urlConnection = null;
try {
url = new URL("your-url-here");

urlConnection = (HttpURLConnection) url
.openConnection();

InputStream in = urlConnection.getInputStream();

InputStreamReader isw = new InputStreamReader(in);

int data = isw.read();
while (data != -1) {
char current = (char) data;
data = isw.read();
System.out.print(current);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (urlConnection != null) {
urlConnection.disconnect();

}
}

But I strongly recommend that instead of re-inventing the wheel for creating a REST client for your android application, try the well-adapted and reliable libraries like Retrofit and Volley, for networking.

They are highly reliable and tested, and remove all the boilerplate code you have to write for network communication.

For more information, I suggest you to study the following article on Retrofit and Volley

Android - Using Volley for Networking

Android -Using Retrofit for Networking

Android REST Tutorial / Sample Project

Here it is one: http://code.tutsplus.com/tutorials/create-a-weather-app-on-android--cms-21587

At the 9 point you will find the class used for the httpCall. This is just the first one I found looking on Google for "meteo app android tutorial" . It seems good.

How to implement android RESTful client with Robospice (or something like this) + OAuth?

It depends. Are you talking about OAuth 1 or OAuth 2? For the former, you could use signpost. For the latter, you could use RoboSpice + Google Http Client + Google OAuth Client Library.

If you use Google Http Client as your network library, what you need to do is to create your own HttpClientSpiceService based on GoogleHttpClientSpiceService, which you can find in RoboSpice. Then, you need something like this:

public static HttpRequestFactory createRequestFactory() {
HttpTransport httpTransport = AndroidHttp.newCompatibleTransport();
return httpTransport.createRequestFactory(new HttpRequestInitializer() {
@Override
public void initialize(HttpRequest request) {
// TODO: authorize or sign request...
// Note that this will authorize/sign ALL the requests you make,
// so you will probably want to improve on that.
}
});
}

The rest is really up to you, but the basics are to implement a way to provide third-party log-in, get the required token and set up the OAuth library of your choice.

Android REST Client using Volley

Yep, volley is sufficient for all network related operations. You can create a singleton for API requests and abstract all logic from rest of application. This article guides through the implementation steps really well.



Related Topics



Leave a reply



Submit