A Surprisingly Complex Task
by Rodgers
My first week at Ona I was assigned a GitHub issue labeled high priority. The GitHub issue was created about 3 weeks before I joined. My task was to upgrade the HTTP library that was being used in the OpenSRP Android client. OpenSRP was using DefaultHttpClient
and it was not working for Android version 5.0 and 5.1. That meant trying to send HTTP requests from OpenSRP Client to OpenSRP Server from Android version 5.1 generated below error.
DefaultHttpClient
is not recommended for use in Android version 5+ for the reasons mentioned in this article. I will not delve on the reasons. See the below summary about why HttpURLConnection
is a better option (excerpt from the article).
For Gingerbread and better,
HttpURLConnection
is the best choice. Its simple API and small size makes it great fit for Android. Transparent compression and response caching reduce network use, improve speed and save battery. New applications should useHttpURLConnection
; it is where we will be spending our energy going forward.
Being new at Ona and having been given a chance to contribute, I quickly started making changes in the opensrp-client-core
library. I was changing POST
and GET
requests to use HttpURLConnection as recommended in the article shared above. This was my chance to learn the code base and I was excited. It is said the best way to learn code is by working on a project.
I also needed to change a method that uploads an image together with other parameters from the OpenSRP client to the OpenSRP server. Having been a developer for a while, this can’t be hard. Right? Wrong. I was in for a rude shock. Sending a multipart request using HttpURLConnection
is not straightforward because the library does not abstract the low-level working of multipart requests. This led me to a newer library by Google called Volley. It turned out that the Volley library is quite good but it does not have multipart request support. To upload an image using Volley, I would first have to convert the image bits to a Base64 string. However, I couldn’t use this approach because the OpenSRP server does not expect an encoded image.
I came across VolleyPlus, a library built on top of Google Volley. VolleyPlus has multipart support, which is asynchronous by default. This means that one cannot put the logic in their asynchronous task or service. This was problematic because the opensrp-client-core
library was implemented to be synchronous, which makes the users of the library responsible for creating a service. Changing the implementation would have required that users of the library implement a callback method. It would also have required liaising with the whole OpenSRP community to build consensus for this change. Being new, and because the task needed to be completed ASAP, I couldn’t take this route.
I found a second library called Retrofit. A quick search online, for Retrofit vs Volley, revealed that Retrofit is preferred over Volley. For my specific use case Retrofit had the same issues as Google Volley. It runs asynchronously by default.
And so I was back to HttpURLConnection
and had no choice but to understand how multipart requests work. Documentation such as the w3 guide helped a great deal. I set up a multipart request on postman and analyzed HTTP headers and body content. Below are screenshots of the raw multipart HTTP request.
With some understanding of how multipart requests work, and with helpful articles, I got a working solution.
If I was to create an Android client from scratch to upload an image (together with other parameters) to a server, I would go with Google Volley. I would also convert the image bits to Base64 string on the client side and decode the string to image bits from the server side.
By working on this task, I got a clear understanding of the OpenSRP code base. It was a great starting point for deeper architectural enhancements of the code base.