Fragmentation is often described as the biggest problem for Android app developers and it has been a problem for both developers and users. The fragmentation problem was best illustrated by the fact that the first version of the Twitter Android app was limited to just 27% of active Android devices. Some other Android apps were installable on more devices, but crashed on many of them. However, fragmentation problems (as generally discussed) are just the tip of the iceberg.
Fragments to fix Fragmentation: I first downloaded the (preview/beta) Android SDK in 2007 and wrote a prototype location-based app at a time when there were no Android devices in the market. However, it wasn’t until last year that we decided to develop and release an app for the Google Play Store.
By this time, fragmentation had become a problem, but over the years, Google had done a fair amount of work (Fragment API, Android Support Library etc.) to alleviate fragmentation. Based on the research I did last year, it seemed like supporting multiple device sizes, screen densities, device capabilities, Android versions etc. was a manageable problem.
We decided that our Economy app (snapshot of the US economy) would use new UI paradigms from Android versions 4.x (Ice Cream Sandwich and Jelly Bean) and yet support phones and tablets (of varying sizes) running any Android version with Gingerbread version 2.3.3 or higher. It is worth noting that the V1 version of our paid app was exclusive to Samsung devices (even though the latest versions – paid and free – can now run on thousands of devices from almost all manufacturers).
Implementing fragmentation fixes: Google’s documentation for solving fragmentation is reasonably good and in theory, you don’t need to have the navigational skills of a Medusan ambassador to track your course for solving fragmentation.
It took some work, but in practice, it was reasonably straightforward to overcome known problems related to fragmentation. For instance, we implemented Action Bar support for older devices running Android 2.3 (even though the action bar was introduced with Android 4.x and wasn’t natively supported in Android 2.3). The app uses hardware acceleration on newer Android versions, but doesn’t depend on any graphics processing unit for older devices.
Fragmentation and Unknown Unknowns: The biggest problem we encountered was related to fragmentation, but wasn’t fragmentation per-se. It was the numerous Android bugs that were specific to one or more specific versions of Android. This wasn’t something I anticipated. I don’t have a list of all the bugs I dealt with, but I’ll list some of the Android quality issues from comments I had written last year.
- Android Section Indexer on 2.x: Our iOS app uses section indices for easy navigation through economic indicators (e.g. tapping “E” would take you to the ‘Employment’ section, ‘H’ to the Housing sector). I considered replicating the iOS section index for our Android app, but decided that it might be better to do section indexing the ‘Android way’. That involved using Android’s fast scroller. Unfortunately, Android’s fast scroller wasn’t ready for prime-time and it had huge display problems with getting refreshed in the 2.x versions of Android. Related problems are documented here and here. The bug didn’t reproduce with Android 4.x. However, for simplicity reasons, I chose to use the same (somewhat) inefficient workaround for the app on all Android versions.
- Dashed lines on 4.x: Canvas.drawLine could draw perfect dashed lines on Android 2.x, but it didn’t work on Android 4.x with hardwareAccelerated turned on. A related problem is documented here. Luckily, the drawPath API worked correctly on all tested Android versions.
- Fill Paint on 3.x: I’m assuming that the Android Honeycomb version family (3.x) set a record for being the least-ever used version of Android. I’d be surprised if it had ever exceeded a 1% share among Android versions, but we supported it because of our need to support older (2.x) and newer (4.x) versions of Android. One of the Honeycomb-only bugs we ran into related to fill-paint not rendering. I worked-around this problem by turning off hardware acceleration for Honeycomb.
- Ellipsize and maxLines for Text: On some versions of Android, Android failed to ellipsize long text if the control had the ‘maxLines’ property set. I didn’t
check to see if the bug was fixed in other versions.
- Webviews and Transparent backgrounds: Transparent backgrounds don’t work with webViews on some versions of Android. One reference to the problem is available here.
- HttpUrlConnection bugs: While writing the app, I tried to keep open the option of supporting Android version 1.6 (or perhaps 2.1). However, Google’s own documentation describes “frustrating bugs” with the usage of HttpUrlConnection in older versions of Android. I would think of these bugs as inexcusable on a 1.0 platform, so it is a bit disappointing to see that they continued on to 2.x versions of the platform.
Eclipse: I haven’t tried the new Android Studio, but no description of Android development problems can be complete without a mention of Eclipse (which is not from Google, but is the most commonly used Android IDE). Crashes and memory problems were annoying, but an even more annoying problem with Eclipse was its occasional sullen refusal to startup. Some of these problems could be worked-around with the –clean flag and luckily, I discovered a blog post with a workaround for the nastiest Eclipse startup problem.
Java: Another source of schedule unpredictability came from bugs introduced by obfuscation and optimization tools I used for Java code. I wish Google added more support for developing Android apps with C++. That would run the gamut from providing prebuilt HTTP libraries (like libCurl – which I built for Android after a lot of effort) to making it possible to create UI controls directly from C++ code (i.e. without being subjected to all the hassles of JNI). It is unlikely that C++ will ever be a fully supported language for Android and most Android-app-developers aren’t going to care about this topic, but I still hope that Google adds some incremental support for C++ developers.
Quality and Development Speed: Facebook is credited with the new-age “move fast and break things” philosophy. I haven’t worked with the Facebook development platform, but I think that Google has been going a bit overboard with the second part of the phrase. Apple and Microsoft seem to provide far more reliable platforms for development. While it may not be entirely reasonable to expect most developers to code with the speed and ease of a Horta tunneling through solid rock, Android’s quality issues make it unnecessarily difficult to write and test code quickly.
Fragmentation Statistics: At the time we launched the V1 version of our paid app, most Android devices were on Gingerbread (v2.3.3 to v2.3.7) even though it had been more than a year since the 4.x versions were launched. However, a very small fraction of Economy app users have been on Gingerbread and I think the percentage of Economy app users on Gingerbread never exceeded around 6%.
Today, Google’s dashboard says that around 24.1% of Android users are on Gingerbread (i.e. Android 2.3.x), but the Gingerbread percentage for our (paid) Economy app is less than 4%. Honeycomb registers at 0% for the Economy app now. So more than 96% of Economy app users are on the 4.x versions of Android. 12% of our users are on KitKat (Android 4.4) even though KitKat only has a 1.1% share of the overall Android market.
As per the latest stats, the free version of our app (Economy USA) has 92% on Android versions 4.x (including 7% on KitKat). 3% of “Economy USA” users are on Honeycomb (Android version 3.x) and 5% on Gingerbread (Android version 2.3.x).
Based on the data we had when development work started (and based on the fact that somewhere around 54% of Android devices were on Gingerbread when we first released the Economy app), I’d say we made the right decision to support Android devices from Gingerbread onwards. However, it was an interesting learning experience to find out that app usage/downloads were very disproportionately skewed towards the latest Android versions (i.e. new devices which ran Android 4.x)
Fragmentation – A strength and weakness: Android’s biggest strength is its ubiquity and the large market-share it has acquired due to the diverse range of devices it supports. So it isn’t unreasonable to have some problems relating to fragmentation. As mentioned earlier, Google has done a good job with providing frameworks to help developers navigate fragmentation issues. Developers interested in reaching large markets shouldn’t mind the overhead of dealing with fragmentation. We spent a lot of time and effort on ensuring that the Economy app (paid and free) were of a high quality on all supported versions of Android.
However, besides being one of the first developers to write Android code (with the preview/beta version of Android six years ago), I’m also an (admittedly infrequent) Android app user who purchased the first Android phone (G1) soon after it launched. So as a developer (who likes development speed/predictability) and as an app user (who is interested in seeing better apps in the play store), I hope that Google plays greater attention to quality issues with future versions of the Android SDK. That will help improve the quality of the average Android app in Google’s play store and it will also make it easier for good developers to ship good quality apps with slightly more predictable development schedules.