September 21, 2010

Electric vehicle research – Flex app

Filed under: Flex,Projects — Steve @ 8:47 PM

Recently I’ve been working on a side-project with Warwick Manufacturing Group to create a simple research-gathering application, using Flex. The application work itself isn’t anything clever, just some video/audio and basic data collection, but the research project is quite interesting – electric vehicles don’t make a lot of sound, and cars that don’t make any sound may cause more pedestrian injuries and accidents because people can’t hear them coming. Researchers are now looking at how to alleviate this problem by generating sound from the vehicle like an engine, but not necessarily the sound of an engine. In fact the sound could be anything at all.

This project is called ELVIN (ELectric Vehicle with Interactive Noise) and is a cute little van that will drive around playing a range of sounds. The purpose of the application is to allow people to evaluate the sounds used by the van, and the data gathered will be used to inform further research into safety and a number of other factors, including nuisance and brand perception – imagine living next to a busy road full of all-electric cars generating the same monotone sound, or a hybrid Ferrari that sounded ‘wrong’. There’s also big potential for aftermarket products; in twenty years’ time instead of a performance exhaust system you might just purchase an upgraded sound.

It’s interesting stuff, and it was fun to create a little app to help this research along. It’s already gathering useful data about perceptions to the current sounds the van is evaluating, but they need as much data as possible – to find out more about the project and to try it for yourself, head to http://go.warwick.ac.uk/elvin

September 7, 2010

Mobile UIs: is AIR + Multiscreen the solution?

Filed under: AIR,Flex,Mobile,UI/UX — Steve @ 12:08 PM

UX consultant Suzanne Ginsburg has posted a good article entitled Android & iPhone App Design: Is it twice the work? It’s a great insight into what to consider when developing an application UI for mobile devices, discussing the cross-platform differences and platform UI conventions that require consideration, including elements like device button types and placement. You have to consider your UI on anything from small phones to large tablet devices, while targeting one OS, and this means you either create separate versions of your app (e.g. Angry Birds and Angry Birds HD on iOS) or carefully optimise your UI design.

After reading the article, I wondered how well Adobe AIR could really address these considerations, especially versus tools like OpenPlug ELIPS that export native code from a Flex project; at the platform level it will remove the need to code in native languages, and arguably would be more ‘native’ than a HTML web app, but AIR won’t be able to reach every platform, and doesn’t directly address the other issues discussed; we need more than the AIR platform on its own to solve this one.

Adobe has a strategy for this  – something it terms ‘multiscreen projects’. This concept goes a long way to allowing developers to get applications onto as many devices/platforms as possible, but it’s still a tricky thing to attempt to solve.  If the tools support the idea of decoupling application logic and views, the abundance and maturity of AS3 MVC frameworks out there now should make it even easier to design an application and target different devices. Good tooling and component libraries has been one of Flex’s strengths, but it would also help to have a strong set of mobile-optimised UI components for each platform. Flex 4.5 (Hero) is the first evidence of this at Adobe’s end, but I’m hopeful we’ll see other open-source and paid component frameworks for mobile Flex being made available.

Finally, going back to Suzanne’s article, all the UX articles I’ve read so far on mobile UI development seem to concentrate on catering for different screen sizes and resolutions with a fixed layout, but part of me wonders why this can’t be partly addressed with fluid layouts. We’ve been doing this for years with HTML (and Flex), and while it can’t deal with extremes, it is possible with careful scaling and layout work to achieve a UI that can work on different resolutions and screens. It’s not ideal, but it’s nothing new either.  One of the key differences between a desktop UI and a mobile UI is windowing, so there is emphasis on a full-screen fixed layouts, but I wonder what the scope is for ‘best-fit’, flexible fullscreen UI layouts in future?

November 4, 2008

AIR FileReference and scope

Filed under: AIR,Development,Flex — Steve @ 8:34 PM

I ran into a small problem recently in my AIR application when using FileReference to initiate and monitor a download operation; no events from a FileReference object created within a method were being fired. After a quick check of the Livedoc entry I found the issue:

if the FileReference object goes out of scope, any upload or download that is not yet completed on that object is canceled upon leaving the scope. Be sure that your FileReference object remains in scope for as long as the upload or download is expected to continue.

So basically a FileReference object needs to be created in such a way that it stays in scope for the duration of your operation; if you instantiate it within a method it there’s a good chance it will go out of scope and any events you were waiting for from it will never fire. The easiest solution is to declare it outside of the method, so instead of:


private function download(event:MouseEvent):void
{
var fileRef:FileReference = new FileReference();
fileRef.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
fileRef.addEventListener(Event.COMPLETE, onComplete);
//etc.
}
you need to do something like this:

private var fileRef:FileReference();
private function download(event:MouseEvent):void
{
fileRef = new FileReference();
fileRef.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
fileRef.addEventListener(Event.COMPLETE, onComplete);
//etc.
}

Sorted. Afterwards I also found more info about this via a couple of useful blog articles here and here.

September 26, 2008

AIR: Rendering native system icons, Pt.1

Filed under: AIR,Development,Flex — Steve @ 2:01 PM

I was asked how I got AIR to display native file icons in a component – it’s pretty easy to do, although my method is a little convoluted to explain without posting reams of code, partly because it’s buried in a sequence of Cairngorm events/commands but also because there a couple of important issues to watch for and handle (see bottom of this entry for those). Here’s an overview:

AIR has support for retrieving the native system icons in whatever supported sizes exist. The icons are stored as a property of each File object as BitmapData, in an array, File.icon.bitmaps. Each element in the array is the same icon at different sizes, e.g. 32×32, 16×16 etc.

In order to get at an icon at a given size, you can’t rely on what sizes are available at a given element position, so you need to create a new (empty) BitmapData object at your target dimension, then iterate through File.icon.bitmaps until you hit the matching-sized BitmapData object. Once you have a match, you can put the matching data into your own BitmapData object. Here’s a brief example:

public function get32Icon():BitmapData {
var myFile:File = new File("C:/foo.txt");
var bmpData:BitmapData = new BitmapData(32, 32);
for (var i:uint = 0; i < myFile.icon.bitmaps.length; i++) {
if (myFile.icon.bitmaps[i].height == bmpData.height) {
bmpData = myFile.icon.bitmaps[i];
}
}
return bmpData;
}
Obviously you need more than the code above to handle situations where the 32×32 icon isn’t available, but that’s a basic way to grab the icon as BitmapData. At this point you could create a new Bitmap object and give it the captured data, but for my application I set the icon data back onto an Object that represents the File object (I actually used an ObjectProxy because I wanted to bind this data to an ItemRenderer later) – again this becomes important later on.

Okay, so now I have my icon data, in an object that also contains other information about the file, like its name etc. To display it in a TileList, or other component, I just use a custom ItemRenderer. I set up an image tag for the icon within the renderer:

<mx:Image width="32" height="32" source="{getIcon(data)}" />
…and then create a method in the renderer to return the icon data to the image component:
private function getIcon(data:Object):Bitmap {
var bmpData:BitmapData = new BitmapData(32, 32);
bmpData = data.icon;
var iconBmp:Bitmap = new Bitmap(bmpData);
return iconBmp;
}
Now each time the ItemRenderer has to render an item, it gets the relevant icon, the filename etc. and displays them within the TileList – easy! Here’s the result, showing the app running in XP and OSX: Files part screen grab

But there are caveats; AIR does not behave consistently on all platforms with icon data. Here are couple of the problems I encountered:

  • Performance. There seem to be some differences in execution time for file system queries in AIR. Originally I had an ArrayCollection of File objects as the DataProvider for the TileList, retrieving icon data for each one in the ItemRenderer as required. On Windows this seemed fine, but on Mac OSX it proved to be very slow, to the point where my app was unusable. I overcame this by using the Flex Profiler to see what was causing the problem, finding that the underlying get icon() execution time was very long on OSX. By grabbing the icon data once, then caching it and other key File properties into an ObjectProxy, I was able to get OSX performance almost on a par with Windows, and this also sped things up elsewhere because I was calling get icon() once, rather than per-item in the renderer. It also improves scrolling performance of the TileList because that component renders items dynamically as they are displayed. In fact you could go one step further than I did and extend UIComponent to improve render performance even more.
  • Missing icons. AIR on Windows won’t retrieve some icons, in particular for .EXE, .TMP and .INI files. These are stored in shell32.dll on XP, but for some reason AIR can’t get to them. I also found one or two similar issues in OSX. AIR on Linux using the most recent AIR beta just returns a null value for File.icon.bitmaps, so rendering native icons is currently impossible. You need to add some way of checking for a missing icon in these cases, and swop it out for an embedded one if you can; I created a temporary workaround where I parse the BitmapData for null pixel values.

The next part of this article will deal with how I got native icons to render for remote files, but I bet you can already guess how that’s done…

September 25, 2008

AIR: Creating a custom status bar

Filed under: AIR,Development,Flex — Steve @ 12:26 PM

It’s easy to create your own customised status bar for AIR applications. For my example, I wanted to be able to display a network status icon that indicates whether the application is connected – this is bound to a state set by AIR’s network service monitor, via Cairngorm.

First of all, in your application MXML file, make sure showStatusBar is set to true, add the statusBarFactory parameter and point it to your custom component:

<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
showStatusBar="true"
statusBarFactory="{new ClassFactory(CustomStatusBar)}">

Then just make a new MXML component called CustomStatusBar and add any elements you want to display in your new status bar. There are a couple of things AIR will be expecting from a StatusBar, most importantly the status setter and getter methods required to display status text:

<?xml version="1.0" encoding="utf-8"?>
<mx:HBox width="100%"
xmlns:mx="http://www.adobe.com/2006/mxml"
backgroundColor="#E3E1E1"
>
<mx:Script>
<![CDATA[
import mx.events.FlexEvent;
import uk.ac.warwick.filesclient.model.AppModel;
[Bindable] private var modelLocator:AppModel = AppModel.getInstance();
[Bindable] public function get status():String
{
return this.statusText.text;
}
public function set status(value:String):void
{
this.statusText.text = value;
}
private function showNetworkStatusIcon():void
{
var path:String = "";
if(modelLocator.isNetworked)
{
statusIcon.source = "greenlight.png";
} else {
statusIcon.source = "greylight.png";
}
}
]]>
</mx:Script>
<mx:Label id="statusText" paddingLeft="7" fontAntiAliasType="advanced"/>
<mx:Image id="statusIcon"
toolTip="Network status"
horizontalAlign="right"
width="100%"
height="10"
verticalAlign="middle"
render="showNetworkStatusIcon()"/>
</mx:HBox>
You can add almost anything you like in there with this technique; animations, custom text etc. Here’s a quick screen grab of my basic custom status bar with its status light on green after a bit more tweaking of the layout and styling – nothing amazing, but its useful to be able to add your own elements when required (click to enlarge);

Status bar

September 18, 2008

Flex unit testing and continuous integration with FlexUnit, Ant and Selenium

Filed under: Flex,Flexunit — Steve @ 3:15 PM

Here’s a couple of really useful guides to setting up a continuous Flex testing and integration framework using FlexUnit, Ant and Selenium, written by my friend and ex-colleague Kieran at Black Pepper, and his colleague Julia. The articles cover setting up FlexUnit and Ant and then creating acceptance tests using FlashSelenium:

September 10, 2008

Flex IoC frameworks: which?

Filed under: Flex,Frameworks — Steve @ 9:11 PM

I need some Flex framework advice; I’m about to start a couple of new AIR projects, and decided that instead of using Cairngorm again it would be a good idea to try a different framework. There’s no particular reason to move away from Cairngorm – I’ve become reasonably comfortable with how it works and what it does, and I like it, but I’d also like to explore other approaches to Flex development. Last time I looked around there were a few alternatives, but in the few months since I posted that entry a number of new frameworks have appeared, and the amount of choice has increased considerably.

At first I thought I’d go for PureMVC – it seems like a popular framework in general, but around here our Java development is based on Spring, and I’d quite like to explore the dependency injection/IoC concepts at the core of Spring in a Flex app, to learn for myself how to apply such patterns in a context I’m familar with.

As far as I can tell, there are three IoC frameworks – Prana is a lightweight IoC container for PureMVC, Mate, which looks really well-thought out, with good documentation, and finally Swiz, which also looks interesting. I’m just not sure which will help me get into IoC as quickly as possible, coming from Cairngorm. I suspect I’ll go for PureMVC with Prana, but if anyone has any advice/insight it would be useful!

August 28, 2008

David Tucker’s 10 common mistakes when building AIR applications

Filed under: Adobe,AIR,Development,Flex — Steve @ 1:04 PM

David Tucker recently posted an article on the Adobe Developer Centre citing 10 common mistakes with developing AIR applications and how to avoid them. I thought I’d quickly compare David’s points against my current AIR project, a remote file-system/transfer manager:

1. Making an application platform specific

David primarily refers here to the UI/UX differences between platforms, but I also found it essential because I encountered significant performance differences with some file system operations (icon getters, mostly), which were fixed with the help of the Flex Profiler. At the moment we can’t test it on the Linux Alpha, but hopefully we’ll be able to try that soon.

2. Not including update capability in an application

We included this as soon as the framework became available and it works very well – whenever the application starts it can check for a newer version of itself, and the user has control over whether to update or not.

3. Changing the application ID after an app has been released

Oops – I ran into this early on; changing the application ID means the update framework will break, amongst other things. Changing the name of your application halfway through the project also risks confusion.

4. Not planning for offline support

Our application relies on a live connection to work, but it does use AIR’s network monitoring APIs to check for a valid connection at startup and then continually monitor connection status, and warns the user if connectivity is lost.

5. Not thinking in AIR

I didn’t find this too difficult – some things were relevant and others weren’t. There have often been moments where I’ve discovered a capability and thought “I didn’t know it could do that”; we do use the application storage directory and the user’s temp directory for file transfers though, and the File , FileStream and FileReference classes were the key to making it work.

6. Using custom chrome to create confusing interfaces

We used the standard chrome, but most of the AIR applications I’ve seen that use custom chrome have done so pretty effectively. One of the most powerful aspects of AIR is that you have very fine control over the UI. As a counter to this though, in addition to the native window chrome there are valid use-cases for having access to native system controls, like toolbars, buttons etc. – platform UI differences can make this even more acute, so I’d like the ability to use standard UI elements where appropriate.

7. Not using the seamless install badge

We implemented this early on – having an install badge makes installation a snap for most people and like the update framework it works well – installation of the AIR runtime can be managed automatically and so far the whole thing has worked fine, except when I broke it myself by not updating the right fields in the updater XML file.

8. Not encrypting sensitive data

Not relevant for this application (yet) – we don’t store any information other than the last file-space used, using a standard SharedObject. AIR has an EncryptedLocalStore for this kind of thing though.

9. Not preserving native interaction

As yet we haven’t got a complete set of keyboard interactions in place (e.g. cut, copy and paste) but some are there. The core interaction type is dragging and dropping, and Flex/AIR gives you control over the process by splitting this action into discreet event-driven stages, so providing visual feedback about whether a drag/drop is allowed can be controlled via your own logic. Something I’ve not yet overcome is how to work with internal and external drag handling at the same time – I may be wrong here but so far it looks like the external drag management only knows about drag in/out operations at the application level, not at the component level, so I need to work on how to use the external drag management to allow items to be dragged into components with the same level of control as the internal drag manager.

A more difficult problem is when a standard component doesn’t quite mimic the operation of a native system control – take the Tree for instance, which will close when its DP is refreshed – in situations like these its nearly always possible to closely replicate the native behaviour by extending or over-riding the component default, but there can be some work involved when finding out what to do. At this point I’ll thank Peter Ent and the excellent Flex Examples Blog for their invaluable resources; they saved me a lot of time.

10. Assuming performance doesn’t matter outside of the browser

In this case, the performance issues highlighted when checking across platforms also highlighted the importance of using the Flex Profiler, the net result being a five-fold increase in speed on OSX and smaller but useful increases on Windows, plus reduced memory usage. The original performance on OSX was bad enough to almost make the application unusable, but after identifying and fixing/working around the problems, the application performs similarly in Windows and OSX.

Thanks to David for writing about what to avoid – fortunately most of them we’d already come across and fixed, so that’s good!

August 19, 2008

FlexCamp London, Aug 28th

Filed under: Flex — Steve @ 2:02 PM

Writing about web page http://www.flexcamp.co.uk/

I really want to go to Flex Camp London but I can’t, so I’ll plug it instead because the programme looks great, the event is free and maybe someone will send me a free t-shirt :-)

July 1, 2008

Flash SEO, Adobe manoeuvres

Filed under: Adobe,Flash,Flex — Steve @ 9:02 PM

Kudos to Adobe, Google and Yahoo for creating the mechanism for Flash content to be indexed on search engines. With one or two reservations (like how to distinguish between application content and a site) I think this is another significant move towards maintaining the ubiquity of Flash. It seems as though Adobe is steadily, but impressively quickly, removing piece by piece the most-cited drawbacks of Flash. Some of the most significant announcements (in no particular order):

  • H.264 video support
  • Open-sourced Flex SDK, BlazeDS
  • Opened access to Flash Player APIs
  • 3D support (thanks to Papervision, Away3D etc.)

Obviously it doesn’t take a genius to work out that, in part, Adobe has had to make some of these moves – HTML5, advances in Javascript and browser technologies promise or already offer many features that up until now Flash had to itself; the canvas and video tags in HTML5, DHTML effects, processing.js, SproutCore, the list goes on – it was inevitable that some of Flash’s functionality would be adopted and integrated into other technologies, but I think that those people who still maintain that they ‘hate Flash’ should still agree that it has been a primary driver of change on the web. This is particularly true in three areas; animation, user experience and video. Flash may responsible in their eyes for evil banner ads and inaccessible sites/UIs, but those things are created by people, and a technology that provides a degree of creative freedom is open to abuse – there are plenty of bad DHTML sites around and more than a fair share of annoying DIV-based floating ads out there already, but there is also a great number of fantastic and successful experiments in user interface design, animation and application experience. Flash has enabled developers to do things on the web they could not have easily done by other means, and those people that attribute bad practice to Flash are both ignorant and in for shock if they believe the same things won’t happen when other technologies catch up. Up until now it’s been far too easy to blame Flash, when Flash isn’t the problem. Use it where it works, not where it doesn’t (like whole sites).

In addition to the technology itself, Adobe has provided the means to develop and deploy it effectively, with the Flex SDK and FlexBuilder. Personally I have no objection to proprietary technologies when they a) work, b) don’t break anything and c) positively drive change and allow people to do things that standards-based technologies often take much longer to enable (and often not quite as well). Flash and Flex won’t be the standard, they will peacefully co-exist with other technologies (along with man, and fish); a single unified standard just isn’t possible in a competitive world, nor is it always desirable. Someone has to innovate, and attacking Flash (or Apple come to to think of it) for being proprietary is like attacking Ferrari for making a better sportscar (and charging for it). If it enables you to go faster, better, and (similar to Java and JS) is on 90-something% of desktops, who can blame Adobe for adding features and functionality that will maintain or increase edge and adoption? And at the same time if it is making key components of its platforms open, regardless of motivation, it’s A Good Thing*. So long as the standards do catch up, it’s fine.

There is I think, one thing left to do at the moment, the final hurdle as I see it – accessibility. It’s kind of in there, but if Adobe could make Flash and Flex as accessible as a typical web page, or at least as easy to make accessible as a web page, it would remove the one last stick with which it gets beaten. In fact and to bring this full circle, the same mechanism by which search indexing now works may also prove the key to unlocking accessibility, so maybe that’s already possible?

*None of these arguments apply to Microsoft, especially the Ferrari analogy. Silverlight is neither better or faster.

Older Posts »