Making networking simpler
There are a lot of useful third-party libs that provide new opportunities for android developers. Today we’ll look at a couple of examples which help make networking easier. More than 95% of applications need to be able to interact with servers, and android developers end up writing similar code for every project. There is a special pattern that describes how an application can “speak” with the server – it’s called REST. Each Android developer works with REST every time they make an app that includes a backend element. I’m going to describe a way to make that interaction simpler and more automatic.
Why not just use AsyncTask and Loader?
Android Framework provides special instruments to handle data sending using the network. For example, there is AsyncTask. But this can’t handle an application lifecycle and this problem can lead to memory leaks. Data may be lost or the application might crash.
The next instrument is Loader. Some developers use it for AsyncTask wrapping. But it’s not really a very good option. Loaders were designed for work with databases, using them for networking doesn’t tend to lead to the best of results.
Another feature of REST is JSON. Unfortunately, Android doesn’t provide a good instrument for JSON processing. We have to use special deserializers like GSON or Jackson. These mappers can create a JSON projection on POJO (plain-old java object; it’s used for data storage) and then deserializing occurs without manual parsing by the developer.
Powerful new library
Thankfully, the guys from Square have created a powerful new library for Android networking. This library provides good abstraction for writing network requests and a good opportunity to both make JSON and deserialize it as well. It uses OkHttp client and using it you’re guaranteed that you won’t have the sorts of issues with servers that you would with SNI etc.
So, if you’re an Android developer and you’ve not used this client, let’s have a go.
Checking out RetroFit
First of all, we’re going to discover a lot of code and understand how it needs to work. Our first target is RetroFit. This was developed by Jake Wharton and his team. These people are known for being the creators of ActionBarSherlock. And of course, RetroFit is ready to be used in production. It’s good because it’s stable, yet manages to remain simple to use.
To start using this library you’ll need to add the lines below to your build.gradle
Don’t be scared that this is in beta – I’ve not experienced any problems using it and I don’t think you will either.
The next step is to create a singleton which contains an instance of the client.
The ROOT_URL – is your base API url.
GsonConverterFactory can produce instances of GSON that are used to serialize java objects to JSON and vice versa.
OkHttp client is used to resolve networking.
So, it’s a base to use if you’re going to create a special service (do not be confused with services from Android Framework).
The service I’m going to show is taken from the official Square website.
This is a simple java interface but it comes with special annotation by RetroFit. You can find a list of these annotations at the official website so I won’t write about all of these. I think it’s easy enough to understand though. We just create a GET-request and send path variable so that the server returns a list of the repos – POJOs (entities) we created before.
If we need to create an object we just do the following:
All of the “magic” is hidden in Call. This handler can start a sync or async network request that will return a result or an error (if there was one). I’m going to show it below, but first I’m going to take a look at what error handling looks like.
So everything sounds good so far, but what if user calls recreate an activity before a result is obtained? RetroFit is just an abstraction to make networking easy. We simply have to find ways to handle these events produced by it.
Java supports Event-Driven Development (EDD). It can be useful if we’re going to create architecture with weak dependence on modules. It’s also a very good opportunity to create anything you want. The main problem with it is bad code navigation for the developer. Fortunately, there are special plugins for IDE that make navigation simpler.
Event-driven architecture with OTTO
Ok, let’s add a little bit of event-driven architecture to our project. First of all, add a special Event Bus. For Java and Android we can choose between Otto and EventBus for doing this. I’m going to use Otto, as it was created specially for Android and is also from Square. Also, I find it to be simpler and more modern.
Add dependency to your build.gradle
Create a singleton that will provide our bus. Now you can create a base subscriber activity or fragment and a base network event. To create an activity (fragment) for example, just add the code below:
BusProvider is simply your singleton that contains Bus (we take it by calling bus()).
After that you can extend your own activities or fragments from this base subscriber.
Supposing you want to create a base event, the situation is more interesting. Create a class as follows:
This class is a base for your future events. There are 3 scenarios in the case of a network call:
- call is started -> call is successfully completed;
- call is started -> call is finished because of an error (no network, server error etc);
- call is started -> call is finished forcibly (unhandled exception, timeout etc).
You need to be able to handle all of those situations. In the first case, the application is going to work normally, in the second case you have to try and handle the existing error or show a message that something went wrong. The third case is really dangerous: if you don’t use any special mechanisms to fix it, the app may crash. EDD is going to add a simple way to make stable code.
Now for the most interesting part of this article. We have the service (not Android Framework Service) and entities that will be used as a store of request and response data. Let’s create an ApiHandler class.
ApiClient contains all our RetroFit services. And we have the Bus inside. This class has to be registered in the application class:
We are ready to create our first event and make our first request.
Let’s create LoadRepositoriesEvent:
Okay, let’s think about what’s going on. We have 3 callbacks that handle the situations I described above. The generic type of OnLoadingStart is String because we don’t use an entity for the request body, but we have a path-variable with String type.
The next step is to subscribe ApiHandler on LoadRepositoriesEvent.OnLoadingStart and enable this handler to produce other events. Just add the following method:
Our handler is sending events now. Let’s take the first one!
If we’re going to execute the method above, we have to produce an event with the type LoadRepositoriesEvent.OnLoadingStart;
For example, in SubscriberActivity we have a button. Just post an event by using bus:
Keep in mind that we have to take events with result; just create two subscribe methods:
That’s it. We have a safe, simple and clean way to network.
Above I’ve described how RetroFit met Otto event bus. It’s a meeting which makes our Android development better.
A word of warning
But finally I’d like to leave you with a word of warning. Use Event Busses carefully because you can send an event from one place to any other. I use events by sending an event from one place and taking it from the same place. It’s cleaner that way than sending from a known place to an unknown.
I hope this helps you with your own apps. Good luck!