Sunday, 25 August 2013

Enterprise Android

Well, in a strange twist of fate, when considering my last post, but I find myself on an Android application for a UK financial institution.  It's a fun project, mostly, but working with Android in an enterprise environment has its challenges.

We have a continuous integration environment based on Jenkins and our build uses Maven.  However, we have a number of dependencies which are not available via Maven central so currently have to install a few jars in each environment we build in.  Not pretty, but we are hoping to get our own repository set up soon.

We have two projects, one that builds the app and one that contains UI tests.

In the main project we have unit tests based on Robolectric and in the UI test project we have tests that use Robotium.  Since we are using Eclipse as our IDE (at the moment) Maven causes us a little pain.  The m2e plugin combined with the m2e-android plugin struggles with dependencies - it can't separate the testing dependencies from the ones used by the app itself and ends up including them all.  As a result Android will try to dex a lot of classes that it doesn't need to, including its own library which causes all kinds of problems.  Our solution was to have separate Maven profiles which you change via the Maven preferences depending on what you want to do; unit testing or running the app (or UI tests).  Generally, I leave Eclipse in "unit testing" mode and run the app from the command line.  However, if I want to run our UI tests then I do have to switch and if you forget to do a proper clean of your environment (I call this "the dance" or "the ritual") it can result in some unexpected results.

Of course, none of that is required outside of Eclipse, so we are waiting for the right time to move to IntelliJ IDEA or Google's own Android Studio based on the same technology allowing us to simplify our build somewhat.

On Jenkins we have three jobs in a kind of pipeline, each job triggering the next:

  • Build for Junit
  • Build (and run) UI tests
  • Build a clean APK
Of course, it's not a proper pipeline because if someone commits while the Junit job is running then the subsequent builds end up using the committed code rather than what was used to execute the unit tests.  I am hoping we will switch to something like Bamboo which should, I believe, allow us to do this properly.

Additionally, there isn't a reliable way to run UI tests at the moment, especially headlessly, so all that job does is compile the UI test project code.  We are planning to use a Mac Mini in the office with a device attached, but will need to unlock the device(s) and login in to the company's WIFI on a daily basis, so that's not going to be very efficient.

We also have a fourth job for doing releases.  With a single click (and after entering a couple of parameters for version numbers, etc) we can build a version of the APK with its manifest properly configured with a new version code and number.  The APK is then published to our Confluence so that interested parties can install and use the application, though anyone who knows where our Jenkins is located is welcome to install the dev version of the APK at any time.

Fragmentation has only been a minor issue so far.  We of course have to design for a number of device sizes and resolutions which is tricky enough, but have noticed some strange behaviour on (wait for it) Samsung devices, especially the S2 running TouchWhiz.

We are also using ActionBarSherlock to provide ActionBar functionality for older devices, but have been glad to hear that the new support library supports it explicitly.   Maven support in Eclipse has been painful particularly ActionBarSherlock has been sherlocked by Google?  It seems so.