Learning to cope with fragmentation
November 29, 2008
It’s 2008; if you’d asked us a few years ago, we might have hoped fragmentation would be a thing of the past by now. It’s still a topic of much debate at industry events and considered a bete noir for anyone launching a mobile problem. But is it really such a problem?
Developing large J2ME applications like Trutap is typically a two-stage process. The first stage is to complete the functionality of the application, generally by targeting a couple of reliable handsets to create a couple of “reference versions”. Once the features are working well and to the satisfaction of the client across the reference handsets, the next phase is to port the product across a greater range of devices and fix any problems that arise.
The porting process is affected by fragmentation (differing availability of phone features), handset limitations (e.g. varying amounts of memory and storage available), and bugs (broken or badly implemented features on specific handsets).
The bad old days
The traditional way to tackle porting is to create separate builds for each device, or family of devices. Conditional compilation and preprocessor statements are used; effecively, portions of the application are written multiple times, each time working around unique quirks of particular handsets. Font sizes, key mappings and the ability to run in the background are typical sources of variance between devices.
When building the application, the portions of code required by each handset are picked, according to a set of characteristics that we assign to each handset. For example, a handset that we know is able to use socket based connections will run a different version of the application to one which is only able to connect via HTTP.
All sorts of problems exist with this approach to porting. It relies upon a prior knowledge of every target handsets capabilities in order to work effectively. That is, all the issues that may affect an application running on any given handset need to be understood before a version can be built. You also end up with a slightly different version, uniquely tailored for every handset that we support. If you are targetting even a moderately broad range of handsets that’s a whole lot of different builds, and keeping track of what code is going in to each can be very difficult. The QA effort is also vastly increased. Once ports are built and tested you can only be confident in delivering the ports to the handsets you have tested on. When new devices come onto the market or existing devices get software upgrades, /more/ porting and testing is needed before these new handsets can be supported.
Things get even worse when your aim is to use restricted APIs or be featured on many operators’ application portals. In order to do this, your application builds need to be thoroughly tested by an official verification body and digitally signed. This is charged on a per-build basis; having many tens of builds of your application will increase these costs dramatically. And remember that every time you release a new feature or bug fixes, you need to recertify.
A different approach
Having been troubled by many of the issues discussed above in the past, we decided to turn this approach on its head with the new version of Trutap. We judiciously apply some carefully chosen prior knowledge of the features common to the devices we’re targeting and let the handsets tell us the rest when we run the application. We can reliably tell on the fly what a device’s screen size is, and whether it supports features such as camera, phonebook or Bluetooth. This way, all devices run essentially the same version of the application.
The consequence of this is that devices that lack certain features will have pieces of the code on there that they will never use. However, for the price of a few superfluous bytes of code on some handsets, is an application that has a much higher chance of *just working* on any phone on which it is loaded. And nowadays there are very few handsets on the market where, even for a large application, the additional code size is a problem.
The Trutap UI just falls into place, scaling itself on the fly with regards to screen size, image assets and font height. And as a result, we’ve spent the bulk of our porting effort solving a few real problems with our target devices, rather than nudging the UI into place on, say, a handset with obscenely large fonts. The end product: a single version of the application, with only three different packages for distribution (each containing small, medium and large icons). The consequence: a clean, maintainable codebase, a relatively painless porting process, and a far simpler testing phase to boot.
So where’s the magic?
Most of the time if UI components are implemented carefully and robustly, they can scale themselves to the resolution of the device they are on and there is no need for magic. Features that require special device functionality can be included or left out as and when it is needed by detecting what APIs are accessible. A handsets colour space can be accounted for by writing to and reading back from hidden test images. Accurate font height can be detected at runtime in similar ways.
With a thorough understanding of handset behaviors it’s nowadays possible to sidestep at runtime most of the problems normally associated with fragmentation.
Fragmentation hasn’t gone away – but it’s not such a problem any more.
Thom Hopper & Douglas Hoskins
Lead Developers, Future Platforms