Using MX Components on Flex/AIR Mobile

I recently was tasked to get part of an older Flex 3 application onto an iPad. Why not, right? I mean, FlashBuilder 4.5.1 and AIR 3.0 are awesome… This should be cake, right?

There’s a lil gotcha – Flex 3, or MX components, ooorrr Halo components, are not exactly welcomed on Mobile.

Fret not! I’ve figured out the task, and it’s rather simple.

HALT! WHO GOES THERE?

Sorry to break the bad news, but there’s a good chance this post won’t do you any good if you’re on Apache Flex.

As the Apache Flex team has made decisions, they’ve slowly been ripping out the MX components, and I’m having people email and tweet me with questions regarding why their app still won’t work.

Simply put, the component is forever gone.

I submit the following for review:

Is there a solution?

I don’t know, and I’m not going to find out… I don’t do Flex anymore (not exactly by choice, but that’s another post).

The only solution I can possibly think of is determine which components you need, and their dependencies, and rip them out into their own library and give them a custom namespace. com.killerspaz.flex.mx is probably what I’d use. Then you just need to change all your references and imports to reflect the new namespacing and it *SHOULD* work. The thing is, you might need to go all the way down to UIComponent for it to work, which will bloat your app pretty significantly.

Anyway, on with the rest of the show…


Why and how are they removed?

Well the why of it is simple. Performance and interaction. Granted, we now had Flex 4 which also allowed for virtualization for most complex components, it didn’t have what we needed: speed and interchangeability between desktop and mobile. A 1-stop shop, if you will. Flex 3 was stuck in the days without touch; thus the lists would all be scrollbars, and no dragging. Not to mention how scrolling used to be handled (yuck!).

As for how… It’s a combination of the mobile theme, and the lack of including it. LOL!  You can compare yourself the build configs for Flex (flex-config.xml) and AIR Mobile (airmobile-config.xml) and see how one includes the mx.swc, while the other doesn’t.

Flex 4 completely reintroduced skinning by separating behavioral and display logic. This is a good thing, especially for mobile where devices have many variant display types. All you need to do is change skins for a different platform/device, and you’re golden. But sometimes we have components that are completely custom, but utilize mostly-light components (i.e., Button, ProgressBar, Container, etc. Basically, not a lot of lists, charts, data rendering, etc. Really custom UIs). Certainly it can’t be THAT bad, right? As it turns out, not for me, no. If you keep it simple and lightweight (i.e., no extra containers, and as close to a flat Display List as possible), it should be OK. That’s my official blessing – if it doesn’t work for you, I blame you! 😛 No really though, it’s not supported by Adobe.

So tell me how to fix it already!

OK, it’s actually very easy. I’ll be using the default paths for Windows users, but this should all translate easily for everyone.

Missing Components

First thing is to include the MX components swc:

  • Right-click your project > Properties.
  • Click Flex Build Path > Library Path tab.
  • Click Add SWC button, and point it to: C:\Program Files\Adobe\Adobe Flash Builder 4.5\sdks\4.5.1\frameworks\libs\mx\mx.swc
Failure to do this step, and probably what brought you to this post in the first place, results in something like the following run-time error:

VerifyError: Error #1014: Class mx.skins.halo::ButtonSkin could not be found.
at flash.display::MovieClip/nextFrame()
at mx.managers::SystemManager/deferredNextFrame()[E:\dev\4.5.1\frameworks\projects\framework\src\mx\managers\SystemManager.as:284]
at mx.managers::SystemManager/preloader_preloaderDocFrameReadyHandler()[E:\dev\4.5.1\frameworks\projects\framework\src\mx\managers\SystemManager.as:2633]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at mx.preloaders::Preloader/timerHandler()[E:\dev\4.5.1\frameworks\projects\framework\src\mx\preloaders\Preloader.as:515]
at flash.utils::Timer/_timerDispatch()
at flash.utils::Timer/tick()

Missing Skins

Next is to source the path to the skins for the defaults.css included in the SWC:
  • Open properties tab if you closed it… Duh.
  • Click Flex Build Path > Source Path tab.
  • Click Add Folder button, and point it to: C:\Program Files\Adobe\Adobe Flash Builder 4.5\sdks\4.5.1\frameworks\projects\mx\src
And failing to do this step yields roughly 26 errors (at least for me) indicating the following:
  • 1120: Access of undefined property BorderSkin.
  • 1172: Definition mx.skins.spark:BorderSkin could not be found.

Anything Else?

You don’t actually need to include the SWC. The source alone will cut it. But I came across the solution in this way, and it shows how the SWC alone doesn’t cut it, but the source does.

Other than that, that’s it! If you run into other components needing included, do essentially the same thing for the proper SWC. If you don’t know which one, feel free to ask!
Advertisements

About killerspaz

I'm a developer that loves to tinker with cutting edge technology. I have recently been playing with the Flash Platform (AS3/Flex), Android (custom roms, replacement apps, scripting), and looking at opportunities in the mobile markets.

Posted on 10.12.2011, in AIR Mobile, Flash Player, Flex and tagged , , , , , , . Bookmark the permalink. 6 Comments.

  1. Hi,
    thanks very much for your post! it was very useful to me!
    Now my flex 4.6 desktop application runs also on an android mobile device, but I still have a problem:
    In the original desktop application I checked for updates on boot to do that I used the update framework.
    Is it possible to do something similar on mobile without using the Android Market?
    Thanks in advance for your help and forgive my english!
    Giulia

    • Hey Giulia,

      First off, pretty great timing 😉 Almost 2 years to the day since my original posting, and I’m glad it was able to help you!

      So if you’re talking about deploying the Android app outside of the Market, there isn’t really any way to deliver updates to the AIR runtime on Android, especially if you bundle AIR with your APK.

      To simply answer your question: No. You have to use the Android Market to trigger update requests to end-users.

      -spaz

  2. he he I had to google for a long long time before finding your post ;-).
    Thanks you agani for your help!
    Have a nice day
    Giulia

  3. Im trying to compile using apache flex 4.11 and even though i followed your steps i still get the problem of mx:Canvas beeing not found. any ideas on what could be wrong?

    • Hey Martynas,

      Sorry to hear you’re having an issue… I actually dropped Flex right as it was gifted to Apache for open source, so I’m not 100% familiar with the changes that have taken place.

      However, I did do a tad bit of research and found the following: http://flex.apache.org/asdoc/mx/controls/package-detail.html

      If you notice, Canvas is not listed.. This got me wondering, did some searching, and thus found this: https://cwiki.apache.org/confluence/display/FLEX/Missing+Spark+Components

      So it turns out that ApacheFlex removed the Canvas class. You might be able to copy it from an older version of Flex and link it in, but the UIComponent it’s based on might be dramatically different. Chances are you’d have to manually find all dependencies, and re-name (or simply just change namespace) for your own personal use.

      I’ll update the OP with this information.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: