HTTP CONNECTIONS
To start off, we first look at HTTP. HTTP stands for Hyper-Text Transfer Protocol. It is the "language" of the web; your browser requests data from web hosts via this mode of communication. The web host then sends back the relevant data, which could be HTML files (webpages), images, videos, anything.
When a client (your browser) talks to a server (the web host), we say that a session has been established. The client sends a HTTP request, and the server replies with a two-part response: a status line and the message body. The status line tells the client whether the request has been understood and replied to correctly. A status code of "200" means everything is OK, perfect. And as well all know, the status code "404" means the item requested was not found. There are many other status codes on Wikipedia here, but the one that we NEED to know is simply "200". This is the one that will come with a sensible message body, whose contents are our main concern.
So what's inside the message body? It depends mainly on the type of HTTP request that was sent by the client. There are two main kinds: GET and POST. A GET request is simply asking the server to return a resource, while a POST request means the client is sending, or "posting", data to the server for some purpose, and the response should describe the outcome of the sending. A good example of a POST request is a login. The client sends the username and password to the server, and the server, after checking, will return a message describing the success or failure of the login. An example of a GET request is asking IVLE for a list of modules; in this case, the message body would contain the list of modules.
However, each server has it's own way of structuring its response content. The list of modules returned by the IVLE server above are usually in JSON format. JSON stands for JavaScript Object Notation, and it's a handy way of dealing with data. JSON has two main data structures: Object and Array. An object is a unordered set of key-value pair mappings, where the keys are strings and the values are either objects, arrays, or primitives (int, boolean, etc). An array is an ordered set of values, and these values can be objects, arrays, or primitives as well. The values are accessed by calling the relevant position in the array. A JSON structure can be written as a string, where the { } curly braces represent objects and [ ] square brackets represent arrays.
ANDROID IMPLEMENTATION
Now that we know how HTTP connections work, we can take a look at how to implement them in an Android app.
I am sure we have all experienced a webpage loading very slowly before, or our internet-based game "lagging". This is usually caused by the server not responding to our computer's HTTP request immediately, but the browser or game needs the data to carry on. In this case, the only thing to do is wait for the response. Waiting is not optimal, as the response may really take ages to reach the client. Also, on single-threaded programs, the waiting time would make the computer appear to have "hung" because the program cannot continue without the response data. Let's make a simple example: you dial your friend on your phone, and while waiting for your friend to pick up the call, you stop doing everything else. No walking, no blinking, no breathing even. It's pretty difficult to live like that.
Fortunately, we can multitask, and so can Android apps (multi-threading). They have the capability of running multiple threads in parallel, which means one program can do a few things at once. Every app has one main thread, which the User Interface (UI) runs on. If we perform a task on the main thread that takes up a lot of time, the UI will freeze for that amount of time. Even if we try to show a loading bar, the bar will freeze at a point while the task runs on the main thread. However, if we run our time-intensive task in the background on a separate thread, then the loading bar can show normally and the UI will not freeze. The background task will then notify the UI thread once it is complete, and then the UI can update itself accordingly.
Android provides us with a nice, easy-to-use Java class called AsyncTask, which allows us to run a background (asynchronized) task and then return the result of the task to the main thread upon completion. We therefore put our HTTP requests in this AsyncTask, so that the program can wait for the server to respond and yet not have to suspend all other activities. Click the hyperlink to view the AsyncTask API if you want more implementation details.
To carry out the HTTP connection in Android, we need to first create a URL object. URL stands for Uniform Resource Locators, which is the string of letters and symbols you see in the address bar. The object is created by defining the URL in the constructor. A HttpURLConnection object is then created from the URL object's openConnection() method. The status code (remember "200" and "404"?) and the response content can then be requested from the server by running getResponseCode() and getInputStream() respectively. The Input Stream received must be read by a stream reader to get the entire response content. Since we have been running on the background thread, we just need to send the response content back to the main thread for the UI to be updated accordingly.
IVLE AND NUSBUDDY SPECIFICS
Let's now focus specifically on the IVLE LAPI's URLs and responses.
The IVLE LAPI (Learning Application Programming Interface) is a collection of URLs to which HTTP requests can be sent, and relevant responses received. We use HTTP connections establish sessions with the IVLE servers such that we can send, request and receive data regarding the following:
- Login
- Modules
- Announcements
- Gradebooks
- Final Exam Timetables
- Student Profile
When a user calls the URL for his profile page, and the data of the profile would be sent back to him. The URL for the Student Profile looks like this:
https://ivle.nus.edu.sg/api/Lapi.svc/Profile_View?APIKey={String}&AuthToken={String}The APIKey is a unique key to identify the caller, while the AuthToken is an authentication token for the current logged-in user's session.
The response content is, by default, structured in the JSON format (as mentioned above). This means we can read the response content as a string. This string is then parsed as an actual JSON object using the Java class called JSONObject. We can now easily extract the data from the response using get() methods on the JSONObject object.
The actual JSON response string looks like this:
{"Results":[{"UserID":"a0108358","Name":"NICHOLAS LUM AIK YONG","Email":"a0108358@nus.edu.sg","Gender":"Male","Faculty":"School of Computing","FirstMajor":"Computer Science (Hons)","SecondMajor":"","MatriculationYear":"2013"}],"Comments":"Valid login!","LastUpdate":"\/Date(1400344894329+0800)\/","LastUpdate_js":"2014-05-18T00:41:34.3293461+08:00"}It's kinda messy in string form because of the nested objects and arrays, but with an online JSON parser, the structure can be made pretty clear:
With this data, we can then build the profile page of the user that requested it.
In our app, we work with JSON quite a bit because it's the default response structure of the LAPI. It is also very convenient to use as a simple data storage object because of the key-value mappings. One drawback is that if the JSON structure in the server's response changes, our methods for extracting the data would break.
SUMMARY
We have covered HTTP requests (GET & POST), the JSON structure, multi-threading in Android with relevant classes, HTTP connection objects and how to deal with responses, and finally an example of how we apply these methods in our NUSBuddy app.
















