When Giants Spin
Tim Cook put out some interesting spin in his keynote at Apple’s WWDC conference back in June last year. He appeared to be comparing iOS, against a specific version of Android, namely 4.4 (or KitKat), stating that “Android fragmentation is turning devices into a toxic hellstew of vulnerabilities”. The force of that much spin made my eyes roll upwards as I heard this (ahem) apples to oranges comparison.
In software development parlance, the major release number for example for Android 4.3 and 4.4 would be 4, and those two releases have minor version numbers of 3 and 4 respectively. Generally the major release number increases when there are major changes in the underlying software, major new features, a big architectural change and/or a big UI redesign (as was the case for iOS 7 for example). Minor versions are usually reserved for smaller updates, tweaks and bug fixes — like what happened when Apple released iOS 8.02, the day after 8.01 (due to problems with the software crippling TouchID and cell service on the new iPhone 6 — oops).
Here Tim was comparing iOS with a single version of Android. Huh? To me, as a developer, that did not make much sense. But getting back to Tim, what about users who still have older devices? Do they not count? Is Apple ignoring them when making this comparison? Maybe. Is this a little bit disingenuous? Probably. What about the actual experience of running new software on older hardware? Im guessing it would not run as well and in fact might be slower — so why upgrade? What if you dont want to upgrade and want to claim back the storage space that the update is using on your device? You’re shit out of luck with that — Apple doesn’t seem to care about that.
Question: What’s the difference between Android 4.2, 4.3 and 4.4 ?
Short Answer: Really not very much if you’re an Android developer.
Slightly Longer Answer: Unless your app is doing something weird that needs a specific version of Android which are pretty rare edge cases, from a developer’s point of view, the API (or Application Programming Interface), the set of functions that you use to write applications, will be pretty much the same.
The truth is that fragmentation in operating systems, languages, frameworks, applications and programming in general has always been an inherent part of technology, the normal result of its continuous cycle of change and evolution through new ideas and innovations. Programmers have had to deal with this for the longest time so its not something completely new. But recently when people talk about fragmentation, its been in a negative way with Android as its poster child.
According to Google’s Android Platform Versions page, Jelly Bean (which includes Android 4.1, 4.2 and 4.3) and KitKat (Android 4.4) have a combined market share greater than 96% — which sounds like a problem but in truth not really — developers are more likely to simply target Android 4.x (meaning any Android release ranging from 4.0 up to, and including Android 4.4), for their apps rather than a specific version because that’s where the majority of Android’s current users are.
In other words, the range of compatible Android releases for an app are a ‘sliding scale’, who’s lowest and highest values will gradually move upwards slowly over time. By design, most Android apps tend to run on a range of versions. The Nook for Android app that I worked on a few years ago for example, runs on any device running Android 2.2 or higher, and its only relatively recently that that had shifted upwards from a previous baseline of Android 2.1. Originally that app could run on any device with Android 1.6 and upwards and remained that way long after Android 2.1 was released. Tim’s comparison in his keynote was mostly irrelevant to those of us who, you know, actually write mobile apps.
It is a testament to how well the Android APIs have been designed, iterated upon and maintained by Google, who have worked hard to make it easy for developers. Case in point: when major new features were added in Android 3.0, those new APIs were backported and made available for use by developers still working with Android 2.3. A similar thing happened again later when new APIs were added to recent major releases, a practice that is quite likely to continue. This maximizes the range of versions of Android your app can run on.
In most cases when an API is published, in use, and the software becomes popular, you owe it to your users (in this case developers writing apps using your API) to keep it stable, keep it backwards-compatible for as long as possible even while you’re fixing bugs and the technology is moving forwards.
Basically, the upshot of all this is that its fragmentation schragmentation, its just hyperbole at its best.
How low can you go or, how wide can that range of versions be? That depends on the app and the developers building it, but it is certainly possible to go all the way back to supporting versions of Android that have very few active users anymore as the nook for Android app demonstrates.
Many years ago Microsoft used similar spin to talk about how fragmented UNIX was and how much easier it was to build and run applications for Windows NT server. That FUD continued for years, most recently used in its campaign against Chromebooks (which have been selling remarkably well by the way). That old adage about necessity being the mother of invention has proven over and over again, but never more so than in the open source and UNIX/Linux communities, where strategies and tools to deal with a multiplatform multiversion universe abound.
Developers old enough to have built early releases of the once popular Perl scripting language from source (Im probably showing my age here :-), may remember the amusing output from Larry Wall’s Configure script as it figured out what sort of platform it was running on to build itself. That was back in the late 80's but the result was that Perl could run on a wide variety of platforms/versions, becoming a sort of Swiss Army knife for developers and system administrators for a long time.
In a similar fashion, things like the X Window system had their own tools to deal with system and version differences to enable them to build and run on as many different systems as possible. Later on, tools such as autoconf and automake became a popular way to abstract away almost all of the platform differences between different flavors of UNIX making cross-platform software relatively easy to build. If you use Homebrew on a Mac today, you’re probably using these tools all the time.
In the Android world, its OK to have several versions of Android out in the wild at the same time. Android’s API has been designed to handle that. Just like its been designed to handle many different kind of devices, with many different form factors with many different screens. That has always been intentional again, by design, from day one. If you want to compare about iOS and Android, Tim should really have been talking about iOS 7.x with Android 4.x.
As someone who owns a few iPads, I know firsthand that fragmentation exists in Apple’s world too despite the reality distortion field Apple lives in. My older iPads may never run iOS 8 or above Im OK with that (and judging from iPad sales, a lot of people are OK with skipping generations and not having the latest). Apple forces your device to download an update even if you dont want it. One could argue that running newer software on older hardware often results in decreased performance and a degraded user experience as a result. The downloaded iOS update annoyingly wastes a chunk of storage sitting on some of these devices with no way to remove it and no way to prevent it from downloading. Recently Ive started seeing less app updates for these older platforms for certain apps. In fact some new apps are no longer available on some devices because Im assuming those devices are now outside the ‘sliding window of versions’ that iOS developers are willing to maintain compatibility with — the sliding window seems much smaller on the iOS side of the aisle.
The question really boils down to how do you deal with multiple versions in operating systems, frameworks and applications? One approach might be to try and maintain backwards compatibility for as long as possible to maximize the return of your investment in a software ecosystem. The other approach might be to force everyone to upgrade regardless of any potential problems. Ill leave it as an trivial exercise to the reader to figure which company chose which approach when comparing iOS and Android.
One thing I have observed over the past 20 years as a developer, is that communities and companies that embrace change, diversity, fragmentation, different platforms and polyglots, inevitably find smart ways to deal with any issues or problems that come up and are usually stronger for it. This usually ends up being good for developers which in turn is good for users.