Product #2: SoundCloud for Androidâ„¢

I released SoundCloud for Androidâ„¢ yesterday.  It’s an Android application built mainly for phones that allows you to play music from SoundCloud.

If you’re not familiar with SoundCloud, it’s a website where artists and DJ’s can upload music.  Users can then see, listen, and comment on this music.  I personally use it for following others who search the site regular and favorite music they like, as well as my favorite DJ’s.  Since I follow them, I find new music that is hand picked by people who have styles similarly to me every week.

I use many music services like Pandora, YouTube, and online radio stations like di.fm and soma.fm.  For my phone, however, I couldn’t get SoundCloud and the existing apps didn’t do what I wanted.  That, and I needed an excuse to build an Android app.

Technical Details

I’ve tested it on a Google NexusOne and a Droid 2.  What was great is that they ran the same.  This was the biggest problem I saw when doing Flash Lite 2 & 3 development for Symbian devices is that they were widly different, and some things worked on one device didn’t work the same, or at all, on others.

I started the application as a pure ActionScript 3 project because I couldn’t figure out what I was doing wrong with the Flex tooling until I was half-way done.  For fun, I ported it to Flex 4 midway through just to compare the performance.  There wasn’t a huge noticeable difference like I thought there would be.  The only things that were noticeable was that the ActionScript 3 one starts up way faster, and the Flex one uses a lot more RAM.

I built the components on top of Keith Peter’s MinimalComps.  I put a ton of my own hacks on top including invalidateProperties to be consistent with the Flex API, as well as a simple state system also similar to Flex for the larger, composited components.  I utilized Robotlegs for the architecture on top of the Views, which will make it a lot easier to port to iPhone/iPad since I’ll just change the GUI code.  For connecting to SoundCloud’s API, I utilized Dorian Roy’s SoundCloud AS3 wrapper.  I had to hack it a little for GET requests, but Dorian knows about it.  I used Intellij in the beginning for about 1 week, and later Flash Builder 4 and mxmlc to test locally, and just ran the command line Terminal on my Mac to create the APK (application files used to install on Android devices), and install to the device connected via USB.

I designed everything in Fireworks, created the site in Dreamweaver, and crated some visual assets in Flash.  Adobe discourages the use of the drawing API on AIR for Android, so some of the things I just made dynamic MovieClips in Flash.

I spent 2 weeks on it in my spare time; 5 minutes one night, 4 hours another, and weekends.

Challenges

There were a lot of challenges.  First off, no one seemed interested in helping me get Flex up and running on the forum.  When Renaun & Joe finally figured out what I was asking, they pointed me to some older setup docs which do work… but are seriously ridiculous.  This isn’t the fault of Adobe; the tooling isn’t ready yet.  However, if it ISN’T ready by the time they launch, they won’t get much traction.  You should be able to just “create an Android Project” in Flash Builder.  The whole create a Flex web project, and then delete your main file, create a pure AS file, and then add AIR nature is just too much hassle.

Secondly, Flex bias is apparent.  Whether they are afraid “slow Flex apps” will give AIR for Android a bad name, they’re still angry at Adobe not treating pure AS3 developers like first class citizens, or are frustrated at all the young whipper snappers who don’t appreciate their pain from the Flash Lite days, it’s pretty clear there are 2 camps.  This isn’t healthy, but I don’t know how to fix it.  On the web, it’s different.  If you have large clients creating large applications, you use Flex.  If you have agency clients, you use Flash; it’s pretty black and white.  On mobile, I reckon we’re still figuring things out.

Third, I was pleasantly surprised by ActionScript’s performance on the devices.  It was the actual refresh rate/frame rates that were depressing.  I’m getting the same FPS I was getting 4 years ago on a Nokia 6680 using ActinScript 2 on Flash Lite 2.1.  That, folks, is depressing (no optimization in both cases).

Fourth, some of the optimizations you’re required to do seem unrealistic and unreasonable.  For example, I get creating bitmaps at the size you’ll actually use them.  But creating bitmaps as powers of 2, manually stopping events from bubbling, and adding final onto your functions everywhere just seems ridiculous.  The cacheAsBitmap, cacheAsBitmapMatrix, and scrollRect uses are still reasonable, although, still challenging in creating applications.  For the bitmaps, it’d help if Adobe created tools to help you ensure you’re bitmaps are optimized for devices size wise, whether export dialogues for Photoshop/Fireworks, or import dialogues for Flash/Flash Builder.  For event bubbling, no clue what Adobe can do.  For the final and other ActionScript optimizations, they just need to make adt better; optimize AS3 for the devices.  This is round 1, so they TOTALLY get a free ride till version 2.  Remember, AS3 for Flash Player 9, while insanely faster than AS1/2, still had a ton of optimization done for it in 10 and even more in 10.1, so clearly they have room to improve here.

Fifth, designing for mobile is hard.  It’s like 2004.  For example PPI, pixels per inch, affects how big your buttons and graphics should be.  The devices we’re running on have insanely high resolutions.  This means that while the graphics may look like Fisher Price (over sized, kid like) on your screen, they can actually be quite small on your phone.  Since the current Android devices I use have horrible touch interactions that aren’t as sensitive nor as responsive as iPhone/iPad, you really need to make buttons larger than the recommended 46×46 to ensure your app is usable.  I recommend 72×72, minimum.  This puts a strain on an already real-estate constrained interface.  You don’t have a lot of room to start with.  Combine those challenges with the need to support rotated interfaces; either you scale your interface, you change it’s look and feel, or you go a step up and change functionality entirely when someone rotates the device to landscape.  Finally, I have to completely redesign the same app for iPhone since they have different GUI guidelines… and iPad because it’s larger…  dear god…

Sixth, coding user interactions for mobile is hard.  For the browser, we’ve never had good integration in Flash.  It took half a decade to get a decent SWFAddress, and even now, in 2010, there are a ton of Flash websites and Flex applications that don’t support the back button correctly.  This is no longer a technological problem, but a design one.  For AIR for Android, we have all the hooks IN the Keyboard code.  This is great.  However, it’s still hard to design components to support the Command pattern with undo so you can “go back”.  Going from a search results screen to a search screen is one thing, but making each part of the app support this, as well as supporting a global history management that can tell which state should go where is… hard.

Seven, there are a lot of weird things mobile does that the desktop does not.  For example, Flash Player 10.1 has optimizations so when you’re SWF isn’t in the foreground browser tab, it’ll use significantly less resources.  For mobile apps, you’re app does something similar when it goes to the background.  However, you have no guarantee it’ll stay there; the OS could decide it needs the resources.  Some people just do a NativeApplication.nativeApplication.exit() to stop the app entirely if it goes into the background; but some apps need to be paused in a certain state of the user gets a phone call for example, or my app which plays music.  I’ll be checking an email, take a call, and then go back to what I was doing.  Your app should support this workflow as well, EVEN IF it was shutdown.  Again, this puts a lot of challenge on your code to ensure your app can support starting up in certain states with data ready to go.  Another thing to is you need to ensure you don’t go below 4 fps (the current default) when you get an Event.DEACTIVATE since some network connects will drop if you go below that.  You can certainly set stage.frameRate to 0.01 if you wish, just make sure you don’t have any network connections you care about.

Eight, with the current build, audio skips when you use the phone, even to just browse/slide through your applications.  My iPhone, and others’, doesn’t do that with the iPod app, nor does it do it when you compile the exact same ActionScript for iPhone (which, technically isn’t ActionScript anymore, hehe).  Adobe knows about it, it’s logged, and they are I’m sure challenged with prioritizing focusing on features, new features, phone specific bugs, runtime specific bugs… I wouldn’t want their job.  While it’s disappointing a simple Sound sound class doesn’t work right while in the background, this is still early builds of a non-released product, so I’m positive they’ll fix it.  Again, once I saw the same code working the same on 2 completely different Android devices, I was sold.

I’m building applications, so these challenges are specific to apps, not really games.  They actually might have more challenges with performance that I didn’t have.

Marketplace: The Good and Bad

The Android Market is light years easier to sell your apps on compared to Apple’s insanity.  I won’t go into the business ramifications in this post, but I will say it’s no lie you can have your app, on a device for sale, in less than 3 minutes.  That’s just full of win.  Being able to immediately see my app for sale on my phone’s marketplace that quickly is just awesome.

The marketplace does have problems, though.  First off, these certificates provide no value.  None.  Using certificates in Android AIR development, again, is light years easier compared to the f’ing insanity you have to go through with iOS.  You just do 1 command line entry, or just publish from CS5, and then compile your app with that file.  However if the file changes, your entire app is considered “different”.  I had create an entirely new app for Android’s market place, for the exact same application, because I accidentally recompiled the cert.  With the exact same info.  The marketplace doesn’t care, either.  Worse, if the apps have the same package name id, it still thinks they are the same even though it just said they were different.  They even discourage you from using their soon to be deprecated licensing system.  Again, certs provide no value, and are a royal pain in the arse.  Screw certs, I hope they die.

Another problem is there isn’t an easy way to inform users of what’s changed in different versions.  In Apple’s AppStore, you’ll often see app updates that list what changed.  Android Marketplace doesn’t give you enough room in the description field to keep a running tally of changes.

Yes, the user feedback commenting system has the same problems Apple’s AppStore does.

Conclusions

All in all, it was an extremely pleasurable experience developing my first app for AIR for Android despite the Flex bias, tools not being ready, and having to suffer in pure AS3 vs. Flex.  It was also nice getting my first sale on the frist day it was posted! I’ll be porting this app over to iPhone/iPad, and then start on some other ideas.  I’ll definitely be doing my next app using Flex vs. pure AS3; even without Hero being ready, the Flex 4.1 SDK worked fine.  I’m not obsessed with getting all the exact user gestures down.

It was also pleasurable to spend just 2 weeks on a simple app vs. 6 months.  Since the applications for mobile can be smaller in scope, you get a quicker feeling of accomplishment.

Thanks to the AIR for Android team for their help, the people on the forum who put up with my mouth and helped, and Adobe for the devices to test this stuff on.

13 Replies to “Product #2: SoundCloud for Androidâ„¢”

  1. @John I can find it on my NexusOne and Droid 2, and Terrance found it on his N1, but Antonio and Terrance can’t find on their Droid X, even though both has Froyo and AIR installed. Hrmm….. #circleK

  2. Gratz with your app, it looks really good!
    When I started with AIR for android, I was amazed that I could just use all the features of Flex (like skinning, layout), it was just really easy to get started because I already knew Flex.
    But the hard part is, just as you said, the scaling of the interface on all those different devices with those insane resolutions (eg. 480 x 800 for a HTC Evo). Another one is performance, having a hard time getting it all transition smoothly from view to view.

  3. btw Jesse, you can create a Flex for android project quite easily. Just follow the following steps in Flash Builder 4:
    1. Before diving into Flash Builder 4, make sure you have a Flex 4 sdk with an AIR 2.5 sdk merged into it.
    2. Once you got that, open up Flash Builder 4 and create a new Flex project. In the wizard you have to choose the “desktop” type instead of the “web” one. Also make sure that you select the Flex 4 with AIR 2.5 sdk from step 1 as the default sdk for the project. After all that finish the wizard.
    3. Now you have a basic AIR application, but in the myApp-app.xml file you will see some android configuration options too (at the bottom of the file).
    4. uncomment the tag block in the myApp-app.xml file.
    5. uncomment the tag and set it to true in the myApp-app.xml file.
    6. uncomment the tag and only leave the “mobileDevice” value in it in the myApp-app.xml file.
    7. That should be all the configuration you have to do. You don’t have to delete the Main.mxml file because you can have a *.mxml file as your main file in Flex for android, no need to replace it with a *.as file (unless you really want to do pure AS3 coding).

  4. Great post Jesse – looking forward to seeing how you go porting it to iOS.

    It’s a pity about the drawing API though – especially when used with the iOS packager. They really need to sort that out cuz it’s killing all my app ideas :(

  5. Hey Jesse,
    great post – I’m currently in the same business as you, creating apps (not games) with AIR on Android & iOS, so I know your pain.. well documented :)

    Anyways I’m not able to find your app in the market (using HTC Desire in Germany) – is there anything known to you?

  6. @Shaun Auto. I have a ton of re-factoring to do before I can start optimizing. I’m not sure if you’ve read the optimizing for Android PDF but it’s pretty insane what they expect you to do, hehe, so I’m focusing on getting the app right first before I start optimizing.

    Regarding Robotlegs optimizing, the Mediator creation/destruction isn’t the biggest hit according to the profiler, it’s the EventMap.dispatch that seems to be using a lot of CPU time.

    Regardless, yes, I definitely plan on doing manual mediation later… it’s just a pain to do, so figured I’d get things working right according to users first, then optimize.

  7. ” But creating bitmaps as powers of 2, manually stopping events from bubbling, and adding final onto your functions everywhere just seems ridiculous. ”

    Absolutely… tons of optimizations need to be made to the compiler and other elements in the tooling to keep us from smacking our thumbs with our hammers. A lot of manual checking exists right now that hopefully will go away very soon.

Comments are closed.