Along with other projects at StatusNet, I’ve been poking at the mobile version of our open-source client reference implementation (still in pre-alpha but getting usable for desktop version). We’re building the client with Appcelerator Titanium, a JavaScript-based cross-platform toolset for development and packaging; the desktop version uses a WebKit-based HTML environment, while the mobile versions use a thin bridge between JS and native controls.
There are some differences between the JavaScript and native bridge implementations between the different target platforms, but cleanly-written backend code can be shared between all platforms, and we’re able to use a single codebase for the mobile UI on both iPhone and Android.
The fun part, though, is with testing and debugging. I’m doing most of the mobile development on my MacBook Pro since I can test both current mobile targets in their respective emulators or real devices from there.
The Android experience
There are several really nice things about the Android SDK setup. First off the download isn’t a bandwidth-shattering 2.3 gigabyte disk image. :) Once installed, I can create custom emulator images with particular combinations of screen resolution and API versions. And, of course, I don’t have to pay $99 and set up a bunch of code-signing keys just to run my test app on a real device!
Android’s SDK emulator is a real, honest-to-god emulator, built around the amazingly versatile QEMU. (I remember using QEMU to simulate an x86_64 system back before I could afford one! Oh the memories…) It runs a complete virtual ARM-based system, booting up a full Linux kernel and Android userland environment.
The good thing about this is that you’re going to be running the exact same real actual code that you’d load onto a real system.
The bad thing is that it takes fricking FOREVER to boot up. Even on a fast modern desktop CPU, emulation is a bit sluggish… booting and general UI actions feel much slower in the emulator than on my Nexus 1 with a 1GHz Snapdragon CPU. And if you accidentally close the emulator you have to wait for it to boot up before relaunching your app…
It’s actually faster in many cases to plug in an Android phone and launch it there. With USB debugging enabled, a native phone can be treated much like the emulator, and Titanium’s wrapper on the SDK can install and launch my app remotely just as quickly as on the emulator — but without waiting for it to boot.
The iPhone experience
Apple went another direction with their iPhone SDK, which has some pluses and minuses. Rather than a true system emulator, the SDK contains an “iPhone Simulator” application, which runs much of the iPhone OS userland as native Intel code on the host system.
The downsides are obvious: you have to compile separately for the simulator and the real, ARM-based devices. Subtle bugs can arise from differences between the systems at both high and low levels. Low-level optimizations such as assembler or vector code won’t even compile, much less run (though that at least isn’t an issue for our JS-based code! ;) An emulator wouldn’t have the same performance characteristics, but could help you confirm that your math is right before sticking it on a real device.
But there are some upsides: most important to me, the simulator launches nearly instantly. This makes a big difference when you’re working in a rapid-development environment without a good debugging infrastructure; working in Titanium’s JavaScript involves a lot of ‘poke in this line of debug to find out wtf is going on, then fix it’ and I might have to restart the app over and over and over while working with it…
The thing that’s amusingly poor with the iPhone is launching the app on a physical device. Thanks to Apple’s tight restrictions on app distribution, running your own program requires buying into Apple’s developer program ($99/year), setting up code-signing keys, an dropping a bunch of certs into iTunes so it’ll be willing to copy your stuff over. The Titanium developer tool can then recompile your app (this time for ARM) and shove it over to iTunes, which performs a sync of your phone to copy the app on. This is kind of annoying if you have a bunch of random crap on your phone and syncing takes forever!
What I’d like
Something in the middle might be nice… working with a real device is a lot easier without jumping through code-signing hoops, and the iTunes mediation seems like something that should be skippable if the toolchain’s better integrated, which could improve the iPhone experience.
Performance and boot time are the biggest issues with the Android emulator; making it boot within a couple seconds would be a huge improvement by itself. Cutting overhead by running a native i386 or x86_64 system image might be nice too, but might not be worth the trade-offs of being able to run native ARM code in the emulator.