With Kana Mind released (even if still in beta form), I figured I’d talk a little bit about the experience of writing a mobile application using Flash (and Adobe AIR) as a platform (there’s also the weird timing of Adobe announcing they won’t be updating the Flash plugin for mobile devices anymore, focusing instead on AIR apps).
The application was written in “pure” AS3 (no components or frameworks used), using FDT 4, and compiled with Flex SDK 126.96.36.19928, and AIR 188.8.131.5280. The project was mostly adapted from the built-in mobile templates provided by Powerflasher, but the iOS and Android project versions (and desktop) were merged together.
Even though the application is only available in the Android platform now, all versions were built together and use the same code. I just haven’t tried releasing an iOS version on Apple’s app store because I’m still adding features to it and fixing some bugs (as far as I know, Apple’s policy doesn’t allow beta applications on their store).
Interestingly, I’ve also been developing a native Android application at work for the past few weeks, so developing this small project allowed me some important insight on how using each platform compares. I’ll talk about it in parts.
The cool thing is that for an ActionScript developer like me, it’s pretty easy to just leverage your knowledge to another platform. You basically learn about the interface caveats and you’re good to go – continue building your mobile application as you would do with a normal website. It’s a pretty rapid development.
Comparing AIR to Android, things can be both good and bad. For example, it’s interesting how it is easy to create custom visual content in Flash – it’s all vector-based (you can resize anything), the display list is pretty easy to deal with. Other important point is that Flash is a pretty mature platform, and many of the most things you’d need in order to develop a proper, rich, user interface are already available in the platform, in the form of easy-to-use libraries, or built-in Flash Player capabilities (don’t get me started with using Events or XML loading in Android – Flash is heaven in comparison).
On the other hand, when developing for a native platform, you can take advantage of the built-in interface frameworks – buttons, scrollers, etc – that are already there and used by everyone. With Flash, you have to build them yourself, and given the differences in user interactivity patterns (e.g., I had to build a
MobileButton class so I could have a
LONG_PRESS event), you can’t just use anything that was developed for the desktop. I also ended up having to rebuild my editable textfield classes to take advantage of native features like StageText. Third-party libraries for all of that already exist, of course, but my point is that if you’re like me and you like to have complete control over your interface elements, expect to have to adapt them to that platform.
Developing the application probably took around 50 hours, on and off, split around my free time. No tablet version is available yet (I don’t have a tablet I can test on), but I believe doing so is trivial – just making sure things work and coming up with slightly different layouts based on screen size conditions (right now, the application works, but of course things are just resized and there’s no landscape mode).
One interesting thing is that testing is, in most ways, easier when you’re using AIR. For Kana Mind, I’d normally compile the application and run it as a desktop application – no emulator needed and, of course, very fast.
Compiling and deploying to an Android mobile device was also pretty easy, since installation on a device can easily be done automatically after compilation.
The issue here is, of course, developing for iOS. Deployment isn’t automatic – you have to compile a new .ipa file and the sync it using iTunes. Luckily, though, I didn’t have to do that very often as the application simply worked the same in Android and iOS.
Finally, at least in my case (I wasn’t many mobile-exclusive features), testing on the devices wasn’t frequently needed; I’d usually spend a few hours coding and testing in the desktop, and then doing a round of tests on a device to make sure performance was OK, and that was it.
Flash developers are generally very well prepared for most fragmentation woes – they’re used to dealing with different screen sizes and CPUs. Doing mobile development introduces news challenges, however: you have to deal with screen density (rounded corners, text size, or element margins, for example, can’t just be pixel-based), and different input schemes (what to do if you want to make your application available to a device that doesn’t support touch screens?).
None of this is a showstopper, however. For screen density, I created a function that takes Capabilities.screenDPI (which is useless in desktops, but mostly correct on devices) into consideration and I use that instead of any actual pixel dimension.
Performance is one of those topics that are very difficult to discuss. People can easily have unrealistic expectations, especially from a platform that is being ported from the desktop to a mobile device. One can easily expect their code to work the same, forgetting it’s a completely different device – with a lot less processing power and memory.
With that being said, it’s easy to be critical of AIR (and Flash) performance in a mobile device. Obviously, it doesn’t work the same as in a PC. My general assessment, however, is that performance of a mobile AIR application is for the most part OK, but not great.
Overall, user interaction and screen updates work well. It is difficult for one to achieve, say, 60fps on an animation, but as long as you keep all your screen rendering in check (knowing when to use bitmap caches and when not to, how to avoid re-renderings of unnecessary elements, etc), it is easy to make a responsive application that works at around 30fps.
The negatives about the platform are the ones that pertain to points the developer has no control over. To me, these are especially true during the application initialization.
The problem for me is that regardless of what you have on your first frame, application initialization takes a long time – up to 6 seconds, on my experience – before any code is even ran or anything is displayed (this is probably especially true of the Android captive runtime, which I have used for Kana Mind). This is true even if you split the application in two frames, like you’d do with an online SWF, to offload code initialization and asset loading.
After the application is initialized, there’s also a few seconds where the application is unresponsive (doing some major memory swapping, I’m guessing), causing user interaction to be glitchy or not work at all.
A long startup time for applications is one of those things that can drive a user crazy. You click an icon and you expect feedback – when that doesn’t happen and you’re just starting at a black screen for too long, it’s easy to just assume the application has crashed or that it’s just some shitty code. It taints the user’s opinion of your application, regardless of what happens later.
When it comes to mobile applications, size matters. Because of this, it’s important to remember the AIR captive runtime adds around 8mb (Android) or 5mb (iOS) to the application size, so it can be pretty bulky. Of course, this expands a little bit once it’s actually installed on a device – Kana Mind itself takes around 20mb of space once it’s installed in my Nexus S.
In Android’s case, if you choose to have a non-captive application instead, it works better – it’s basically your SWF size – but then it requires users to install the AIR runtime.
Regardless of the result, building an application using AIR is one of those things I really wanted to do, to get a chance to test the platform and find its pros and cons myself. As it turns out, there’s plenty of those, so it’s hard to get to a final verdict on whether someone should use it or not.
If you’re building something quickly or free and you want to use the same code on iOS and Android (including mobile devices and tablets) and potentially desktop, AIR is the way to go. You can have the same project (with maybe just some conditional layout or user interface elements) and, at least in my case, cross-platform testing is seldom necessary. It’s a very rapid development and testing workflow and, if you spend time building some user interface and application libraries to work around the caveats of the platform, you’ll be able to create cross-platform applications in the blink of an eye.
On the other hand, it looks like the platform has reached its limits in terms of performance and there’s not much that can be done (I’d love to be wrong, though). Mobile AIR applications are usable, but not exactly snappy, even if you take all the performance tricks out of the bag. The unavoidable truth is, if you want the best performance for your application, there’s no way around it: it has to be a native application.
I’m pretty proud of how Kana Mind turned out and I’ll probably do a few parallel applications for other languages, as I like how well the teaching algorithm works, and still use it as my excuse to play with AIR. But if I was developing a serious, bigger, commercial application, I’m not sure I’d have gone the AIR route.
TL;DR: AIR is good. But not for every case.
Update (27-February-2012): I just tested the same application on an Android 4.0.4 (Ice Cream Sandwich) phone and I have to say, it’s so much faster. My application, on this same phone (Nexus S 4G), used to get around 10-30fps when under Android 2.3.7, with frequent render stuttering. Although I don’t have a FPS counter to back me up, under the new version, it feels like it’s getting a fixed 60fps, with no stutters. It still takes a few seconds to start up the first time, but the fact that it’s much faster overall – with no tweaks like hardware acceleration – makes a strong case for AIR on Android phones. That’s not to say it’s a perfect solution; as of now, version 4 is still only available on 1% of the Android phones out there, and it’ll take 1 or 2 years until it’s a valid target version. It does, however, paint a brighter future than I expected for Adobe’s platform.