A cowboy walks into the bar. He waits for the bartender to come by and orders for a rye whiskey. The bartender returns after a while, hands over the whiskey to the cowboy and moves on to other customers. Same rules apply in the client-server network architecture. It starts with the client sending a HTTP request to the server and the server responding back to the client. Wait, were you expecting a walks-into-a-bar joke? Well, apologies for the disappointment.
Let’s get down to the brass tacks. Assume that I want to procure the list of all the companies featuring during the placements. I can do so by sending a GET request to the server. The response which I receive from the server contains status information about the request and also the requested content. Now, it is crucial that I craft up the correct query string which I would be sending in the URL of the GET request.
Note: A GET request is made to receive response from the server while a POST request is made to send response to server. They are two of the most common HTTP methods; PUT, HEAD, DELETE, PATCH and OPTIONS being others.
The server returns the content in JSON format which will be converted behind the scene into a Java object. The JSON data looks something like this:
[ { "id": 2, "name": "Microsoft", "poc_name": null, "poc_phone": null, "poc_email": null, "company_type": "Dream", "url": "/hrms/placement/companies/2.json" }, { "id": 3, "name": "Adobe Systems", "poc_name": null, "poc_phone": null, "poc_email": null, "company_type": "Dream", "url": "/hrms/placement/companies/3.json" }, { "id": 4, "name": "Intuit", "poc_name": null, "poc_phone": null, "poc_email": null, "company_type": "Dream", "url": "/hrms/placement/companies/4.json" } ]
Let’s halt for a while and address the elephant in the room.
What is it that is enabling me to make the HTTP calls?
Android Volley, it is. It is a networking library which was introduced to make networking calls much easier, faster without writing tons of code.
Until the release of Volley, the canonical Java class java.net.HttpURLConnection
and the Apache org.apache.http.client
were the only tools available to Android programmers to develop a RESTful system between a client and a remote backend. Putting aside for a moment the fact that these two classes aren’t exempt from bugs, it should be noted how everything that went beyond a simple HTTP transaction had to be written ex novo. If you wanted to cache images or prioritize requests, you had to develop it from scratch. Volley was tailored to cater to these needs.
By default all the Volley network calls works asynchronously, so we don’t have to worry about using asynctask anymore.
Volley comes with lot of features. Some of them are
- Request queuing and prioritization
- Effective request cache and memory management
- Extensibility and customization of the library to our needs
- Cancelling the requests
Volley? Why the name?
A client sends a request to a server over the net. It comes back. Metaphor complete xD
Coming back to the JSON data we fetched earlier, how do you parse this data into something useful?
Volley comes into play, again! Let’s put our hands in the dough. So here is the instance of how the JSON data fetched above is parsed into something which can be displayed to the user.
public static ArrayList<Company> companyList;
companyList = new ArrayList<Company>();
String url ="https://dev.iris.nitk.ac.in/hrms/placement/companies.json"
JsonArrayRequest arrayRequest = new JsonArrayRequest (Request.Method.GET, url, null, new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
try {
for (int i = 0; i < response.length(); i++) {
JSONObject object = jsonArray.getJSONObject(i);
String id = companies.getString("id");
String name = companies.getString("name");
String poc_name = companies.getString("poc_name");
String poc_phone = companies.getString("poc_phone");
String poc_email = companies.getString("poc_email");
String company_type = companies.getString("company_type");
String url = companies.getString("url");
Company company = new Company(id, name, poc_name, poc_phone, poc_email, company_type, url);
companyList.add(company);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
SingletonRequestQueue.getInstance(MainActivity.context).addToRequestQueue(arrayRequest);
Beautiful. Isn’t it? As you can see, the type of result is already set to JSONArray. As before, the first parameter of the constructor is the HTTP method to use. You then provide the URL to fetch the JSON from. The third variable in the example above is null. This is fine as it indicates that no parameters will be posted along with the request. Finally, you have the listener to receive the JSON response and an error listener. You can pass in null if you want to ignore errors.
There is something more it. You might ask, how is the parsed data ultimately displayed on your device screen? Let’s take a minor detour to answer this query.
Android Application Architecture
Let’s assume that we want to display these companies as a list in our Android app. For this we will use the ListView
provided by Android. However, ListView
doesn’t actually contain any data themselves. It is just a UI element without data in it. Now, we shall populate this ListView
by using an Android adapter.
Adapter is an interface whose implementations provide data and control the display of that data. ListView
owns adapter that completely control its display. The adapter loads data from the network from the API Server and manufactures views for the ListView
upon request. So adapters control the content displayed in the list as well as how to display it.
Here is what the adapter file for the code above looks like:
class CompanyAdapter extends ArrayAdapter<Company>{
public CompanyAdapter(Activity context, ArrayList<Company> companies)
{
super(context, 0, companies);
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
View listItemView = convertView;
if(listItemView == null) {
listItemView = LayoutInflater.from(getContext()).inflate(
R.layout.list_company, parent, false);
}
final Company currentCompany = getItem(position);
TextView nameView = listItemView.findViewById(R.id.company_name);
nameView.setText(currentCompany.getName());
return listItemView;
}
}
How does Volley work under the hood?
Volley works on three different levels with each level operating on its own thread.
Working of Android Volley
- Main Thread: On the main thread, one is only allowed to fire the request and handle the response.
- Cache and Network Threads: When a request is added to the queue, several things happens under the hood. First, Volley checks if the request can be serviced from cache. If it can, the cached response is read, parsed, and delivered. Otherwise it is passed to the network thread.On the network thread, a round-robin with a series of threads is constantly working. The first available network thread dequeues the request, makes the HTTP request, parses the response, and writes it to cache. To finish, it dispatches the parsed response back to the main thread where our listeners are waiting to handle the result.
My experiences with Volley
I have been using Android Volley for developing the Training and Placement module for IRIS Android app. It comes in quite handy for handling multiple request types, such as string and JSON. In fact, Volley is perfect for API calls such as JSON objects and lists, and it makes working with RESTful applications easy and smooth. Image loading is one of the more useful features of Volley. Just writing a custom ImageLoader and complementing it with the LRU bitmap cache does the work.
Google has made considerable efforts to improve the performance of the Volley library by improving memory usage patterns and by passing callbacks to the main thread in a batch. This has relatively reduced context switching and hence makes the app faster.
You can check out some Volley tutorials here and here to get yourself started.