Archive for the ‘Flash’ Category

Android for ActionScript developers, part 5: Fragmentation is real

Much is said about the Android platform’s fragmentation problem. However, the fact that there are a lot of politics and conflicts of interest at play creates an echo chamber that is difficult to wade through – especially if you reach articles by websites with an obvious bias.

The reality is that fragmentation is a serious problem but not in the way most people think. Having devices with different features – such as different screen sizes, or additional hardware – is something that can easily be dealt with by using conditionals and proper, flexible UI solutions; it is something that requires more testing time, but also nothing Flash developers hadn’t had to deal with in the past, for example. This is obviously exacerbated by the amount of different devices already available on the Android ecosystem, but developers for other platforms, such as Windows 8 and iOS, will have to deal with the same problems as soon as the number of device models supporting it reach a certain number and start spanning different sets of features (e.g. games on iOS having to deal with different resolutions based on the new iPhone screen densities, or whether they can use a gyroscope or not).

Rather than a problem with hardware differences in different devices, the real problem with Android is the OS version fragmentation problem due to the considerably slow adoption of OS updates. For developers, it means that if they want to reach the majority of the users out there, they need to develop for (at least) Android version 2.3.3, a version that was released in February 2011. And that only gives them roughly 60% of the market out there; if they want to increase their reach to about 90%, they need to use version 2.2, which was released in May 2010.

This creates a problem because the Android system has changed considerably in the last few iterations – it’s now on version 4.0.3. Many of the best packages – like Fragments, Renderscript – were made available after version 2, as have many additional features, such as hardware accelerated 2d elements, multicore support, and UI and speed enhancements. When you’re stuck with an older version of the system, it means you’ll have more trouble doing something (commonly having to recreate a feature that’s already available on a newer version of the system) and end up with a result that’s less than optimal, just because the system is not as optimized as it could have been.

It’s no surprise that Google Chrome for the Android was released for the latest version of the system – a version that only runs on 1% of the devices out there: it was probably a lot easier than creating something for older versions, and performance should be better. But even though this update should start being released soon to many existing devices, it should be at least one year until it reaches any viable penetration to warrant Android 4 exclusive releases.

As a developer, it’s especially sad reading the reference site and finding a feature you want, but realizing you cannot use it because it’s only available on a version of the system that’s newer than the one you’re targeting. Even doing simple stuff like setting the alpha of a UI element requires version 3.0 of the system. There are workarounds, but they’re more painful than they should be.

Luckily, one (almost unspoken about) solution to this problem of lack of updated libraries is the compatibility package. Google realized the OS version penetration problem and, as such, packaged ported versions of some libraries (that would normally only be available on later version of the system) into a library that can even be used by version 1.6 of the system (which means “API Level” 4). One especially useful class is the ViewPager, a class that I wish I had discovered sooner. This solves many of the problems a developer has to deal with, but the lack of certain features – like easy hardware acceleration for UI elements – are still saddening.

The Android system is ever evolving. The software itself is getting better by the day; however, if you’re stuck with an old version, it can be a pretty painful experience. Using the compatibility package is the least a developer in that position can do to keep his or her sanity while developing a new application, but I can only hope that device sellers and phone providers will get their act together and speed up deployment of new Android versions. I’m not very optimistic; even with the Nexus line of phones – which would normally mean clean, Google-controlled Android versions – updates can be painfully slow and, many times, not even available. The fragmentation problem, manifested in the form of version lag, is very real, and it’s not going away.

Update (29-February-2012): here is a great post analyzing the version fragmentation that the Android ecosystem suffers from.

Android for ActionScript developers, part 4: Reading XML is nuts

One of the most baffling things for me when I started messing around with Android was dealing with XML files, especially parsing them. In Actionscript, parsing a XML is simple enough:

var xml:XML = new XML("<root>Some-stuff</root>");

And you can get children pretty easily using E4X, or the standard syntax. For example, to get a list of nodes:

var children:XMLList = xml.child("someNodeName");

It is not quite so easy in Java. In a way, due to the way the platform is constructed – you have a lower level access to most of the moving parts of the platform – XML parsing is a bit more convoluted, since you have to parse the data yourself. When I first set out to parse a XML response in Java, most of the documentation I was reading was recommending me using something called a Sax Parser. This is how you would do the top level parsing, using code lifted from this tutorial:

SAXParserFactory spf = SAXParserFactory.newInstance();
try {
	//get a new instance of parser
	SAXParser sp = spf.newSAXParser();
	//parse the file and also register this class for call backs
	sp.parse("employees.xml", this);
}catch(SAXException se) {
	se.printStackTrace();
}catch(ParserConfigurationException pce) {
	pce.printStackTrace();
}catch (IOException ie) {
	ie.printStackTrace();
}

This handles the basic parsing call. But, of course, you first have to create a parser before you can run that. This low-level XML parsing works similarly to some other languages (I specifically remember doing something similar in PHP), in the sense that you setup callbacks to certain events (starting a node, or ending one) and deal with the data that gets passed to you in each of these calls. Again, using code from the tutorial linked above:

//Event Handlers
public void startElement(String uri, String localName, String qName,
	Attributes attributes) throws SAXException {
	//reset
	tempVal = "";
	if(qName.equalsIgnoreCase("Employee")) {
		//create a new instance of employee
		tempEmp = new Employee();
		tempEmp.setType(attributes.getValue("type"));
	}
}

public void characters(char[] ch, int start, int length) throws SAXException {
	tempVal = new String(ch,start,length);
}

public void endElement(String uri, String localName,
	String qName) throws SAXException {

	if(qName.equalsIgnoreCase("Employee")) {
		//add it to the list
		myEmpls.add(tempEmp);

	}else if (qName.equalsIgnoreCase("Name")) {
		tempEmp.setName(tempVal);
	}else if (qName.equalsIgnoreCase("Id")) {
		tempEmp.setId(Integer.parseInt(tempVal));
	}else if (qName.equalsIgnoreCase("Age")) {
		tempEmp.setAge(Integer.parseInt(tempVal));
	}
}

This is some parsing for a very basic XML schema:

<?xml version="1.0" encoding="UTF-8"?>
<Personnel>
	<Employee type="permanent">
		<Name>Seagull</Name>
		<Id>3674</Id>
		<Age>34</Age>
	</Employee>
</Personnel>

The problem with this approach is simple to understand – this parser will only work for this specific XML schema. For every new XML you use, you need a new parsing class. This makes sense if you always want to have your XML transformed into something specific (a collection of value objects for instance), but if you want to do some XML reading and a rapid iteration through a node, it means you have to go through the whole process of creating a separate parser class, a new class to hold the values, doing the parsing, and only then iterating through the new object you created. If you have a complex XML schema, this can get pretty annoying. Comparing this to the one-line parsing method I was used to in Flash made me realize a big part of the ethos of the Java platform: everything is a bit more complicated, like zigzagging through a bunch of obstacles when going from point A to point B, and it’s up to you to create shortcuts to make your life easier.

Often, there is more than one way to do something in Java, without a single officially established way. That’s also true of XML. The same tutorial I linked, for instance, has a second example, using a DOM parser to read the XML. It’s a much more flexible solution.

What nags me about this is that maybe due to the over-engineering of the platform, additional solutions are, many times, still too complicated to use repeatedly. Consider an example of how to read an XML using XPath syntax, found in this page:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true); // never forget this!
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse("books.xml");

// Create an XPath factory, and use the factory to read an object we can use
XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();

// Create an object and evaluate it
XPathExpression expr = xpath.compile("//book[author='Neal Stephenson']/title/text()");
Object result = expr.evaluate(doc, XPathConstants.NODESET);

// Cast the result to a DOM NodeList and iterate through that to find all the titles:
NodeList nodes = (NodeList) result;
for (int i = 0; i < nodes.getLength(); i++) {
   	System.out.println(nodes.item(i).getNodeValue());
}

In a way, I understand the need for approaches like this; they're giving you more power, and allowing you to tailor the results to your needs in terms of result and performance.

However, something should be said about easiness and speed of development. If I have an XML object in front of me - in whatever shape or form - do I really want to write a complicated parser or additional classes every time I want to lift the value of a node from it? I find any (potential) disadvantages of higher-level libraries hard to justify in the face of making actual development time shorter - buying me time I could spend in UI polishing and responsiveness, for example.

So from my high-level platform developer point of view, the problem seems to be that, with Java, you have to look around for a solution that meets your needs. Much like some features of the ActionScript language - like tweening - are lacking and normally solved by third party libraries, the Java world seem to benefit immensely from libraries created by developers that may have a different view of how their development time should be spent. In that sense, I know now that there are several, more sensible XML solutions out there - but that didn't stop me rolling my own extremely simple XML parsing solution that, admittedly, mimics most of the way XML parsing works in ActionScript; with no XPath/E4X parsing, but with a simple enough interface that instantiating a XML from a number of source types, iterating through nodes, and reading any kind of data from it is pretty straightforward.

XML parsing in Java is pretty symbolic of the whole platform: you have absolute power over what you're doing, and how, but that also means you have to get the building blocks together, or at least employ blocks built by someone else, to create a solution you're comfortable with. Otherwise, you'll feel you are constantly repeating yourself, creating the same factories and builders over and over again. In the Java world, it's as if the industrial revolution never ended.

Android for ActionScript developers, part 3: Threads and blocking

Multithreading support – the ability to run different blocks of code separately, in parallel – has always been a requested feature in the Flash/ActionScript community (and it’s, indeed, coming). But the reality is, due to the way the platform is designed, reasons to use concurrency in Flash are very rare. I’m sure some exist, but it’s not part of the tasks you normally have to program into a website or even a generic application.

The reason is simple. Consider the following code:

var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadComplete);
loader.load("myimage.jpg");

protected function onLoadComplete(__e:Event) {
	trace("Image loaded!");
}

The code will attempt to load an image and, when that is complete, display a message stating it did so.

The important thing to notice about this code is that it is non-blocking; when the call to load() is made, Flash just continues execution of your next line of code as if nothing happened. This is one of the many moments where Flash executes your requests asynchronously, letting you know later (via an event) when that request has been completed (or reporting on its progress, or any other event conditions necessary).

One big hurdle I had when I started working with Java is realizing that the language is, indeed, blocking everything you’re doing. Consider a similar code to load an image on Android:

URL fileURL = null;
try {
	fileURL = new URL("http://domain.com/myimage.jpg");
} catch (MalformedURLException e) {
	Log.e("", "Error: URL is malformed");
}
try {
	HttpURLConnection connection = (HttpURLConnection)fileURL.openConnection();
	connection.setDoInput(true);
	connection.connect();
	InputStream inputStream = connection.getInputStream();

	Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
	myImageView.setImageBitmap(bitmap);
} catch (IOException e) {
	Log.e("", "Error: I/O Exception");
}

Apart from syntactical differences, the big distinction about this code is that when the Android system reaches the lines that make the connection and download the file, the whole execution thread hangs and waits for the file to download, continuing after it’s done. That’s why a completion event is not necessary; no code will be executed until the task is complete anyway.

This creates a situation where it’s very easy for a developer to write code that will technically work, but also hijack the main (UI) thread while running complex pieces of code, freezing the application. In an environment like this, it’s easy to see why threading is extremely relevant. It’s not just sugar; it’s something absolutely needed for a responsive user experience.

The solution in Android is creating a separate process for that kind of problem – a thread that executes a task, then, implements event or message dispatching as needed. The code is a bit more involved and there are different ways to do it; you have to decide between Threads or AsyncTasks, for starters. That’s why one of the first things I’ve done when working with the Android platform was build classes that allow me to work on the main UI thread without having to worry about blocking user execution all the time. With names like TextLoader, Loader, and XMLLoader, they essentially emulate what the Flash platform already does by default.

Maybe because they’re not as necessary in Flash, I used to think that working with threads was this untouchable apogee of low-level programming techniques that would only be necessary in crazily computationally expensive tasks. The reality, however, is quite different: on a platform like Android, if you don’t use separate threads for things that take more than a few milliseconds, you are doing something wrong.

Android for ActionScript developers, part 2: Events and listeners

The first thing that made me pause when working with Java is discovering that it doesn’t have event listeners – at least not in the sense that I’ve come to expect based on my ActionScript experience.

In ActionScript 3, you attach an event to an object like so:

myObject.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);

protected function onMouseDown(e:Event): void {
    trace("The object " + e.target + " was clicked.");
}

Considering that the second parameter to the addEventListener method is a function reference – a closure – you can reuse the same function in as many instances of as many objects as you like. Furthermore, you can attach several listeners to the same event on the same instance; this means that several different objects can track the same event.

Creating custom events is also fairly easy. In way, you don’t need any real class; just a string. You can certainly do something like:

myObject.addEventListener("mysuperevent", onSuperEventTriggered);

And you can easily trigger them from your object:

dispatchEvent(new Event("mysuperevent"));

You can also create new custom events, if you wish, so the event dispatched can carry more data with it. This can be done with separate event classes, like so:

public class DestructionEvent extends Event {

	// Enums
	public static const EXPLODED:String = "exploded";	// Object has exploded
	public static const IMPLODED:String = "imploded";	// Object has imploded

	// Properties
	_customData = __customData;

	// ================================================================================================================
	// CONSTRUCTOR ----------------------------------------------------------------------------------------------------

	public function DestructionEvent(__type:String, __customData:Object, __bubbles:Boolean = false, __cancelable:Boolean = false) {
		super(__type, __bubbles, __cancelable);
		_customData = __customData;
	}

	override public function clone(): Event {
		return new NavigableSpriteEvent(type, bubbles, cancelable);
	}

	public function get customData(): Object {
		return _customData;
	}

They can be easily dispatched:

dispatchEvent(new DestructionEvent(DestructionEvent.EXPLODED, {id:myId, somedata:"Some data"}));

And easily caught:

myObject.addEventListener(DestructionEvent.EXPLODED, onExploded);

protected function onExploded(e:DestructionEvent): void {
    trace("The object " + e.target + " has exploded, and it was carrying the " + e.customData + " custom data with it.");
}

Despite some syntax awkwardness (especially when transitioning from the ActionScript 1 and ActionScript 2 models), some performance problems, and some great alternatives, this system does the job well, allowing developers to glue together encapsulated pieces of code pretty seamlessly, and is supported consistently through the AS3 ecosystem.

Hence my surprise when I got to Java.

First of all, Java doesn’t allow closures (at least not yet), so you can’t pass functions as parameters for anything. This means I couldn’t even build an event dispatching (or signals) system like the ones I was used to in ActionScript 3.

The first examples I found covering the event model on Java were pretty awful. They were something like this:

public class MyClass implements OnClickListener {

	public MyClass() {
		Button myButton = new Button();
		myButton.setOnClickListener(this);
	}

	public void onClick(Object o) {
		Log.v("", "Object " + o + " was clicked);
	}
}

The problem with this is obvious: by forcing the instance that contains an object to implement a listener interface to the object, it doesn’t allow me to track the same event from two objects at the same time (or even listeners that have method name collisions). In my above example, if I wanted to have two buttons, I would need an additional condition inside onClick to detect where the event came from. This could easily get ugly.

The reason why I’m mentioning it here is because that kind of example was quite easy to find and it baffled me for a while that someone would adopt that kind of design for complex applications.

As it turns out, however, event listeners in Java are a little bit better than what that typical example makes it look like. You can create and extend an object of a class (even an interface!) inline – so the real way to write the above code is something like this:

public class MyClass {

	public MyClass() {
		Button myButton = new Button();
		myButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(Object o) {
				Log.v("", "Object " + o + " was clicked);
			}
		});
	}
}

Still a little bit strange to me (still used to AS3 I suppose), but much easier to read and use.

Implementing custom events is also pretty easy. Here, again, I did a mistake initially – I thought you had to create a separate class for every kind of event you wanted. My initial classes were always awkwardly accompanied by a bunch of separate interfaces for events, making my own packages pretty polluted.

As it turns out, there’s a better, cleaner way of declaring events too: as interfaces declared inside the classes themselves, and then referenced from outside. This seems to be the norm in Java conventions. In a nutshell, my classes that require an event look like so (in a hypothetical button clas):

public class MyButton {

	// Instance references
	protected OnClickListener onClickListener;

	// Constructor
	public MyButton() {
		...
	}

	// Public methods
	public void setOnClickListener(OnClickListener __listener) {
		onClickListener = __listener;
	}

	// Interfaces
	public interface OnClickListener {
		public void onClick(MyButton __button);
	}

	// Internal dispatching
	protected void dispatchOnClick() {
		if (onClickListener != null) onClickListener.onClick(this);
	}
}

And using it is just like before:

myButton.setOnClickListener(new MyButton.OnClickListener() {
	@Override
	public void onClick(Object o) {
		Log.v("", "Object " + o + " was clicked);
	}
});

Notice how the name is used when instantiating (new MyButton.OnClickListener()) to avoid collisions. I’ve seen this in several differenr packages (mainly Android’s own framework) and it’s a pretty clever solution to avoid name collision given that so many events can share the same name.

All in all, despite the syntactical differences, event dispatching in Java works the same as in ActionScript 3, expect for one major caveat: listeners are normally set, not added. This means you cannot have more than one listener to the same event on the same object.

Personally, I’ve added a multi-listener feature to some of my classes (it’s just a matter of adding to an ArrayList afterall), but the real problem is that none of the established classes follow that pattern. So… be careful when adding your listeners in Java, lest you erase a listener that was set previously.

Android for ActionScript developers, part 1: Getters and setters

I’m just in the process of finishing the development of an Android application at work. This reminds me that since I’ve been a dedicated Flash developer for more than a decade, switching to a different platform was an interesting challenge, and one worth sharing.

Luckily, I saved a lot of notes in the process, and I thought I’d share my impressions here, so other developers – of any platform, but Flash/ActionScript especially – could read them and know what to expect when doing development for the Android platform. My posts will focus on specific topics and while they won’t cover the whole range of features or capabilities of the Android platform (there are many other places and better articles for that), they’ll cover what surprised me the most.

My first note is: Java has no getters and setters to work as mutators and accessors in the same way that ActionScript (or C#, or others) support them.

Consider the following code:

protected var _position:int;

public function get position():int {
    return _position:int;
}

public function set position(__position:int):void {
    _position = __position;
}

What this code does is create a position pseudo-variable. When you read its value, it simply returns the value of the protected variable _position, which wouldn’t normally be accessible to other objects. Likewise, when you set that property to a value, it simply sets the value of position. This means those methods could then be used as if they were a normal variable, like so:

someObject.position = 0;
trace (someObject.position); // 0

Using a getter/setter combination like that is, of course, fairly useless, since it’s just passing values along, without providing any additional benefit. The real advantage is when you need to have additional code bound to either method. Consider, for instance, that a getter method doesn’t need to be bound to the value of an existing variable, but instead generate its own return value as needed:

public function get numBrokenItems():int {
    // Calculate the number of broken items on a list
    var brokenItems:int = 0;
    for (int i = 0; i < items.length; i++) {
        if (items[i].isBroken) brokenItems++;
    }

    return brokenItems;
}

// Traces the number of "broken items" in this instance
trace(someObject.numBrokenItems);

In the same way, a setter can be used to run additional code after a variable is changed:

public function set x(__x:int):void {
    // Simple implementation of a redrawing method for illustration purposes only
    // This is not very efficient; for a real implementation of position getter/setters
    // it'd be better to have display invalidation and a deferred redraw()

    // Sets the new value
    _x = __x;

    // Redraws the item
    redraw();

    // Dispatches an event
    dispatchEvent(new MyObjectEvents(MyObjectEvents.MOVED));
}

// Changes myObject's 'x' variable, redraws it, and dispatches an event that it has moved
myObject.x = 10;

It should be obvious by now that I’m particularly fond of using getters and setters – I believe they give developers a lot of control, especially for fluid, animated interfaces; getters and setters are a requirement if you need easy tweening with any generic tweening library out there, for example.

Alas, it is not so in the Java world, where Android developers finds themselves in.

In Java, you can still have accessors and mutators (even though some people hate them), but they are normal functions and methods. It’d look like this:

protected int _position;

public int getPosition() {
    return _position;
}

public void setPosition(int __position) {
    _position = __position;
}

This means you access them as you would normally access functions:

someObject.setPosition(0);
Log.v("", someObject.getPosition()); // 0

It works well; I’m yet to see a real disadvantage (you can’t do the typical ActionScript-style tween syntax on Java anyway, so the main advantage of having a pseudo-variable like in ActionScript is moot). But the result is a situation where you’ll always dealing with a bunch of different functions for every class, and, in my opinion, a polluted interface where every variable access is duplicated and actual variables are pretty much never used. There’s probably an argument to be made here in favor of simplicity and encapsulation (whether the value is generated or comes from a hidden variable), but not sure whether that’s enough; right now I’m keeping an open mind and accepting the language for what it is (my love for getter/setters notwithstanding) since it’s a new platform and assumptions can be risky.

A mobile AIR application post-mortem

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 4.5.1.21328, and AIR 3.0.0.4080.  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.

FDT 4 with the Kana Mind project opened

FDT 4 with the Kana Mind project opened

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.

Coding

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.

Kana Mind TO-DO notes

Kana Mind TO-DO notes

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).

Testing

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.

Kana Mind running as a desktop application

Kana Mind running as a desktop application (purple boxes are for debugging purposes)

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.

Some Kana Mind device testing

Some Kana Mind device testing

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.

Adaptation

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

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.

Size

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.

Conclusion

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.

Kana Mind, a mobile AIR Application to help you learn Japanese

Almost 20 years ago, I decided I wanted to try and learn Japanese. Other than studying the language’s grammar and vocabulary, I also had to learn the basic symbols used by the Japanese language – the Kana – so I could read Japanese properly. The Kana consists of 96 symbols (plus variants) which are to syllables in the roman alphabet (the romaji). This process of reading or writing a symbol as a syllable is called romanization. In short, if you know how to read Kana, you can read simple Japanese aloud, even if you don’t know what it means.

I learned the symbols with the help of books and software, and I got to a point where I could read Kana-based Japanese writing pretty well. Then I promptly forgot everything. I’d remember a symbol or two, but in general, one year later, my knowledge of Kana was back to the starting point.

The problem with learning a new language is that if you don’t practice frequently, it’s very easy to forget everything you’ve learned, maybe especially one that depends so much on learning new characters. That’s when it dawned on me – I needed to have some software that helped me keep the symbols and their romaji counterparts memorized. A software that would understand when I forgot something, and help me record that again in my brain. Not just something to test me, but something to target the testing in what was more relevant for me.

I kept that idea in my mind for many years, and testing development of an Adobe AIR-based application was the perfect excuse to build it in my free time. Therefore, I have just submitted a new application to the Android market that does just that. It’s called Kana Mind.

The application is still in beta. This means it works well, but it’s missing some features like proper support for big screens (tablets) and landscape mode. I’m still working on it. The iOS version is working pretty well too, but will only be submitted to the market once it’s out of beta. But even in beta form, this is the kind of application I wish I had many years ago (and, luckily, beta-testing and playing it is already making me relearn Kana in the subway).

There are many games that get you to test your Kana knowledge by matching it with their romaji equivalent – memory games, crossword games, dictionary games, and the alike. However, none of them seem to be as serious about teaching, testing and reinforcing memorization, nor as focused on the task of memorizing Kana, as I believe Kana Mind is.

The way Kana Mind works is by slowly presenting you just a handful of symbols at first. So when you start the game, it cycles through the same 8 symbols – those are the “active” characters you’re being tested against.

While playing, if you pick the wrong pair, the game marks that option as wrong. Then you need to try again, until you get it right; the game then proceeds to the next character in the series of active characters, cycling through them in a randomized fashion.

After you get the same character right 7 times in a row, the game assumes you’re proficient with that character, so it marks as learned and adds a new symbol to the mix. So get something wrong again and again, and you’ll see it often; get it right several times in a row, and it’ll be skipped pretty quickly. This goes on until you reach “proficiency” in all characters. Symbols get more difficult to match as you progress, too, since symbols are grouped into levels of difficulty (although this is invisible to the user).

One additional aspect of the whole algorithm is that after 7 days of reaching proficiency with a specific character, the game assumes your knowledge of that character is decaying, and it throws it again in the mix of characters. Get it right once, and it won’t bother you again; get it wrong, and back it is to the list of characters you’re being tested again.

After you “finish” the game – reaching proficiency in all characters – the game uses its “maintenance” algorithm, always testing you against characters that you haven’t seen in a while.

This helps students that are already proficient enough with the language to keep their knowledge fresh – one needs only to play the game once in a while to test themselves. If you have trouble with any character, the game will be sure to make note of that and test you again and again.

And finally, Kana Mind is a serious application, but overall it was done more as a test than anything else. Therefore, it’s a free application.

I’ll have a more technical post about the pros and cons of the Adobe AIR platform soon. In the meantime, comments and suggestions about the application are always welcome.

Using StageText for AIR applications

Adobe AIR 3 includes a great new feature: StageText. Using the normal TextField for text input works just fine, but this new TextField-like class allows you to control your text input more closely (especially on mobile devices) with many options like auto capitalization, software keyboard type, and more. It has its caveats (it’s a separate class, and it gets added to the top of the stage, so there’s no display list control) but overall it’s a great feature addition to Adobe AIR and the Flash platform as a whole.

Only that when I was trying to use it (with Flex 4.5 and AIR 3), it wouldn’t work, but instead fail with this error message during execution (even though StageText was included on airglobal.swc):

Exception fault: VerifyError: Error #1014: Class flash.text::StageText could not be found.

An online search for the error and its meaning provided no results (!) – information on the new class is pretty hard to come by. So after some trial and error (and luckily stumbling into this video about setting up FDT for Adobe AIR 3 and Flash Player 11 development), the reason is: you need to tell the Flex SDK compiler to compile against a newer version of the SWF format that enables that feature.

So the solution is simple: just add this parameter to your Flex SDK compilation settings (this is in addition to any target-player switch already present).

--swf-version=13

It should then work flawlessly.

Stage Text example

Read more about that switch here. The same applies when using StageVideo.

The developer’s guide to browser adoption rates

Just posted a new article on NetMagazine: the developer’s guide to browser adoption rates. It analyzes the speed of adoption of new browser versions and compare them to each other, and to the Flash Player plugin adoption.

Much like my old Flash video playback benchmark, this is one of those things that started with an assumption that I wanted to investigate further (in this case, “browser updates take much longer than Flash Player updates”) but that ended up with unexpected results that made me look at things from a different perspective.

Platform adoption rates

The takeout of all of it is that while the adoption rate of new Flash Player versions is pretty good (and getting better), browser update rates are getting better too, and Google Chrome is leading the pack, with a user adoption rate that is even faster than Flash, overall (and the frequency of updates released has nothing to do with it). It means new HTML features are making it out to user’s computers faster than ever, with the exception of IE, which continues to hold the platform in the past.

There’s more to it, of course, as it’s a lengthy article (but one with pretty charts to look at). So for the full story, continue on to the developer’s guide to browser adoption rates.

Setting up an Android environment for Flash mobile applications development

Update (May 2012): The information below applies to an old version of FDT and is deprecated. If you’re using FDT 5.5 or newer (which I recommend), you can skip most of it and just follow the IDE’s own mobile project setup steps, which are must easier and straightforward.

There’s something wonderful about using the same code base for an application and running it on several different devices. I knew that was possible with the Flash platform – given the newly found ubiquity of Adobe AIR support on mobile devices – but that’s still the kind of thing that always warrants setting up your development workflow first.

I finally spent part of this weekend setting up such an environment for Flash development that allows me to run my application locally (on the desktop) and on a device (Android) without any porting hassle and I can state that things are nearly as good as they get when it comes to ease of development; it just takes a while to get it running.

(I haven’t tried iOS yet because I don’t have an iOS device at home, but that’s the next step).

I’m using FDT and the Flex SDK with Adobe AIR for development. And while FDT’s blog has a ton of information on how to set up an environment for mobile devices, it’s not complete as it skips the mobile device SDK parts (I guess it assumes the developer already has everything in place). So because of this, I thought I’d share my notes on how to set up a  Flash development environment with Android as a target, with links to the necessary information on each step.

(I’m using FDT because it’s my IDE of choice. Everything I’m doing is possible with other ActionScript development tools – even Notepad – and luckily no commercial tools are required for compilation or deployment, but of course setting up your environment and project templates will be very different depending on your preferred IDE).

So those are the steps:

  1. Download and install FDT in case you don’t have it.
  2. Install the Flex SDK 4.5.1 and Adobe AIR 2.7.1. Extract them to the same folder (Flex already comes with AIR, but it’s an older version). For a tutorial on this, see this blog post (first video).
  3. Install the Android SDK. This can be done by following the instructions on this page. You don’t need to download Eclipse, Eclipse plugins, samples, or the different APIs, however; that’s for native Android development. You’ll only be using the Android tools and, sometimes, the driver for your specific device.
  4. Setup your phone for debugging by following these notes (skip step 1, this is done automatically). This includes installing the drivers for your device, if needed.
    • Note for Nexus S users on a Windows machine: the documentation mentions that the USB Drivers for your devices are at “…/android-sdk-windows/usb_driver“. This is incorrect; that’s version 3 of the drivers. You need version 4, which is actually at “…/android-sdk-windows/extras/google/usb_driver“.
  5. Connect your device to your computer using the USB cable.
  6. Test your device. If you did everything correctly, running the command like adb devices (from “…/android-sdk-windows/platform-tools/“)  should list a connected device ID.
  7. You can now run FDT and create a new project using the built-in mobile development templates. See this blog post again for more information (second video). Make sure to create your project on the default FDT workspace – if you use a separate folder, the ANT tool won’t work so your application will be compiled but never deployed (I’m still investigating this, as I always use separate folders).
  8. Now you can finally write your application’s code. When testing, run the wireless-based debug profile (found on “Run” > “Debug Configurations”) as explained in that blog post again. Your application will be automatically compiled, installed and ran on the device. Notice that you’ll need a wireless network already setup so the device can connect back to your computer to get the result of the trace() statements; for more information on how debugging is done, see the reference to the fdt.startDebugger command, and to AIR’s -connect parameter.

The cool thing about compiling and debugging like that is, if you use the first launch profile, you compile a normal application running on your computer, like you would do with a normal AIR or Flash application; but if you use the other launch profiles, it runs on your device. It’s a super easy testing and deploying method and it certainly beats, say, using the Android emulator for native Android development (although, of course, you’ll have to keep performance in mind since your application will run much faster as a desktop AIR application).

With a few conditionals (or even different “Main” classes), it should be easy to have the same code based being used for deployment on several different platforms. Right now, FDT’s mobile templates offer two separate templates for Android and iOS development, but merging them together for a single project that supports everything should be possible. I plan to create a template that does that as soon as I have some free time and can get my hands on an iOS device.