Life @ NCP

not everyone needs to go outside to have fun

PAF #3 SvenskaOrd Show and Tell

You can grab a copy of the apk (~5mb) , or build it yourself from the repo . The repo’s front page also has some explanation about how to use the app.

Its appearance hasn’t changed much from the midway point, it was mostly adding new features and backporting compatibility. Yes, it is compatible with Gingerbread but at some cost.

SvenskaOrd was interesting for a number of reasons. I started off with the idea that I would be able to do the backend first, which would make TDD easier and hook it up to the frontend, where the dev cycle was slower. Coming from using Corona in BishiBashi , where changes were reflected in seconds, using the Android SDK’s native simulator felt like watching paint dry at times. The sequence of events over the fortnight went something like this:

  • Marty came up with some mockups
  • I sketched out a data model
  • In Android Studio, used TDD to build out the logic independent of Android itself. Persistence still in-memory, just enough to make tests pass [expand title=”…”]

    • Unfortunately, the new Gradle based build system doesn’t quite support the notion of unit tests. Only instrumentTests, where the tests are run in the simulator and have access to the app classes under test.
    • The fact that the simulator is involved is bad enough, but the notion of unit tests is not even supported, i.e. you have to jump through numerous hoops to get simulator-independent unit tests working (much of the build-hackery involved can now be simplified thanks to the gradle-android-test-plugin).
    • Even then, you can’t seem to run unit tests and get results natively within Android Studio, the best anyone seems to be able to do is to run a Gradle task and inspect the test report

    [/expand]

    • Started work on the UI, calling backend methods
    • Introduced ORMLite to do persistence  [expand title=”…”]

      • This is where things really started to get hairy. Testing database interactions usually requires the simulator as its associated classes require an application context. Trying to mock out the provided android framework jars in the SDK is no help because they are mostly stubs and the implementation is only available after being linked on the actual device or simulator. You know you’ve run into this when you hit ‘java.lang.RuntimeException: Stub!'.
      • Thankfully, there is an awesome project called Robolectric that provides minimal stubbed versions of core framework classes, even allowing you to shadow specific classes if you need to. This seems to be the canonical library to use for Android unit testing when framework classes are involved.

      [/expand]

      • Realise that much of Android’s provided classes for view-to-db adapters assume you’re going with the framework and using ContentProviders / SomeCursorAdapter  / CursorLoader for async database access. This is somewhat at odds with ORMs which return you object graphs. I ended up Implementing ContentProviders that return Cursors from ORMLite’s CloseableIterators. [expand title=”…”]

        • While OrmLite has support for turning its CloseableIterators to Android cursors for use in CursorAdapters, it doesn’t help cases where you need to traverse the object graph and all you have is a cursor. If you were handcrafting your own SQL, you would include all of the object graph you need in your projection so the cursor has access, but OrmLite doesn’t support projections across multiple tables; you can only select columns from a single table.
        • As an alternative, you can simply roll your own AsyncTaskLoader to retrieve object graph collections from OrmLite, but you lose the flexibility of iterable collections

        [/expand]

        • Then introduce Roboguice to try and remove much boilerplate view retrieval. And saddened to realise that it actually requires the use of Android’s support library [expand title=”…”]

          • The support library adds newer features in a way that is compatible with older Android versions. For the most part this involved changing the inheritance hierarchy and implemented interfaces from something like app.android.Activity to app.android.support.v4.Activity .
          • Initially I thought this was a good idea anyway, since the majority of devices were still on Gingerbread when I last looked a year or two ago. How things have changed – http://developer.android.com/about/dashboards/index.html . The majority of devices are now ICS (API 15) or newer. Still, it seemed like a good exercise so I went ahead

          [/expand]

          • Introduce ActionBarSherlock (ABS) for better backward compatibility as I was using the actionbar for navigation, then realise [expand title=”…”]

            • You can’t use local aars without some build-hackery
            • RoboGuice uses inheritance. ActionBarSherlock uses inheritance. Multiple inheritance is not cool. But someone’s already done the grunt work to combine the hierarchies in roboguice-sherlock
            • You might get compile and runtime goodness with older devices using the support libraries and ABS, but you cannot prevent themes from missing 🙁 It turns out that the default theme for ICS+ devices is Holo , but it’s not available on Gingerbread or Froyo.
            • The kicker is ABS used to bundle a backported version of the Holo theme so it was available, but removed the backported dialog theme in newer versions because it wasn’t relevant to the library itself. I agree with the motivation, and sure, it’s just duplicating some xml and assets, but it certainly would have been nice to offer it as a separate download since they had already done the legwork.

            [/expand]

            • Discover a bunch of bugs because I hadn’t really tested the UI bits. TDD kind of fell by the wayside when I started hooking up UI components.

          I had thought it would be a straightforward affair, given the large number of developers already on Android, but there’s still enough there that could probably span a few blogs or series of howto entries. Fleshing out entries takes time. Concrete examples and walkthroughs take time. It all just takes time, but perhaps I’ll do it as a PAF some time in the not too distant future.

          I’ll probably put it on the app store after Marty’s nutted out the bugs but do download and have a play with it too. Issue trackers are enabled on all the repositories I’ve made public 😛