Mobile dev trade-offs: emulator vs simulator

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.

3 thoughts on “Mobile dev trade-offs: emulator vs simulator”

  1. Android phones take a long time to boot in hardware, too. At least they got rid of the annoying full-second sqllite “busy timeout” contention back-off delay, but I have a feeling that is lowered from the default at the end of the boot sequence, which is full of contention delays. I’m not sure if there’s a way to make that happen sooner, but I’m asking.

  2. The reply so far is: …post to android-platform or file a bug…. [or a patch].

    I have no idea where the bug tracker is for the Android boot sequence, and even if I found it I’m sure it would ask me to pick categories and sub-categories with which I am unfamiliar, but I sent this to http://groups.google.com/group/android-platform

    About a year ago Dan Bornstein filed a bug from “some guy on the internet” to reduce the sqllite “busy timeout” contention delay from the default 1000 milliseconds to something much smaller, and on the next Android release after that things got so much faster.

    Would you please ask your database guy to consider reducing that default at the beginning of the Android boot sequence, instead of the end? I recommend running the usual QA suite to make sure it doesn’t break anything, and measuring the difference in boot times. I apologize if the default delay reduction is already occurring as early as possible.

    I regret I don’t know where the correct bug tracker is for this, and am not skilled enough to put a patch together in less than a week, I’d estimate. I don’t have that kind of free time for something which I believe involves moving a single sqllite function call.

    Thanks again, in advance!

    –Some guy on the internet

  3. I too have experienced the “joys” of waiting for Android emu to boot. Since I’ve got 4GB of RAM in my laptop (which I used to develop on), I just booted up the emu and left it running. I really saw no point in shutting it down. Of course, the occasional glitch in the emu, or mistaken alt+f4 puts you back into a holding pattern for 10mn reboot.

Comments are closed.