The last Android application I was working on needed a server side. We decided to use the Google App Engine infrastructure (GAE for short) for that purpose. A problem arose of how to connect the two and make them talk to each other. This is not a trivial task to accomplish. The solution I needed had to satisfy the following requirements:
- The client side must work on Android. Since Android is a mobile platform the solution on the client side must be lightweight and efficient.
- The server side must work on GAE. The GAE platform cannot run any Java library (we use the Java flavor of GAE) you throw at it because of the security features the good people at Google implemented.
- Allow easy object transfer between client and server. I use a lot of Java objects both on the client and on the server side (surprise, surprise). When the need arises to process an object on the server I need to be able to send it to the server and continue the processing there in as few steps as possible. The same goes when I need to get some objects from the GAE database to the client. The objects can contain primitive Java data types, collections and other (simpler) objects.
- The solution should require as little boilerplate code as possible (no manual message parsing, etc.)
- Some kind of support for handling cookies. Google Account authentication and other authentication schemes use cookies in their implementations.
I considered these solutions:
- GWT RPC - cannot use GWT on a pure java client, although gwtrpccommlayer looks promising but it just got published and i did not have time to test it.
- gwt-syncproxy - GWT on pure Java clients. Not mature enough at the time I tested it (arround May 2010).
- Web Services - these are too heavy and complex for the Android platform. Also several implementations do not work on GAE (JAX-WS and JAX-RPC).
- GET/POST requests with JSON/XML embedded - did not try it but I had the feeling that it involves too much boilerplate code and reinventing the wheel.
- Restlet - this is a nice library. I used it in a previous project (which did not involve Android) and it works well. But I must confess that I am not a big fan of the Rest concept. Also, as you can probably tell from my first pick, I was looking for a RPC like solution which uses even less boilerplate code than the Rest solution.
- Hessian - this was the best match for what I had in mind.
The Hessian library is very small (only 376 kilobytes and has no other dependencies). It works on Android (although not perfectly) and on GAE (also not perfectly). I will describe what you need to do to make it work on both in the next couple of posts so stay tuned. It allows you to transfer almost any kind of objects (within reason) between Android and GAE. As for the ease of use here is an example. First we define the contract (a fancy way to say interface):
public interface Service {
public String echo(String message);
}
Next we implement it on the server side:
public class ServiceImpl extends HessianServlet
implements Service {
public String echo(String message){
return "Server echoes:" + message;
}
}
Here is how we use this on the client:
HessianProxyFactory factory = new HessianProxyFactory();
Service service = (Service) factory.
create(Service.class, "http://myserver/echo");
String serverEcho = service.echo("Hello world!");
// use server echo...
This is the main reason why I prefer this solution to the Rest and/or GET/POST requests with JSON/XML. You can just define an interface in Java, implement it on the server and use it on the client. You can name the methods of your interface in any meaningful way (or not) you like. IDE refactoring just works. Also, instead of
String-s in the example you can use arbitrary objects as parameters or return value of your interface methods. Moreover, when the method is invoked on the server the input parameters are ready to be used. There is no need to use JSON parsers or other methods to create the input parameters from HTTP requests. This is also true on the client side as the Hessian framework takes care of the serialization/deserialization of all your objects. This is one of the cleanest and simplest way I have seen to implement the communication between client and server. However, cookie support is not built into the Hessian framework but the framework is extensible so it is fairly easy to add cookie support to Hessian. I will write about this in a future post.
I would also like to hear from you. What are you using in your Android applications to communicate with a GAE backend?