blog

Using Metadata Frame for a Preloader

This article was sleeping in my drafts for a while, and I am happy I managed to finish it today. There are multiple ways to create preloader for your ActionScript applications with flex compiler. The easiest and my prefered way is to use Frame metadata.

This metadata is a hint to the compiler that the class containing the metadata would like to be bootstrapped by the cited factory. In other words, when you build an application based on mx.core.Application, that isn’t actually the “root” class of the SWF. The root class is actually a compiler-generated subclass of mx.managers.SystemManager (Modular Applications)

Using it as a preloader is very easy thing, because you can apply it on your existing projects without almost any intervention with the original code. Open you main application class and add Frame metadata before class definition:

[Frame(factoryClass="sk.yoz.myapp.Preloader")]
public class MyApp extends Sprite
{
    public function MyApp(preloader:Preloader)
    {
        ...

What it does is, that your class is not manufactured by default but it is waiting until factory class does it. In our case manufacture class is a preloader.

package sk.yoz.myapp.preloader
{
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.events.Event;
	import flash.events.ProgressEvent;
	import flash.utils.getDefinitionByName;

	public class Preloader extends Sprite
	{
		public function Preloader()
		{
			super();
			stage.align = StageAlign.TOP_LEFT;

			updateProgress();
			addEventListener(Event.ENTER_FRAME, updateProgress);
			stage.addEventListener(Event.RESIZE, updateProgress);
			loaderInfo.addEventListener(ProgressEvent.PROGRESS, updateProgress);
			loaderInfo.addEventListener(Event.COMPLETE, onComplete);
		}

		private function updateProgress(... rest):void
		{
			trace(loaderInfo.bytesLoaded / loaderInfo.bytesTotal);
		}

		private function onComplete(event:Event):void
		{
			removeEventListener(Event.ENTER_FRAME, updateProgress);
			stage.removeEventListener(Event.RESIZE, updateProgress);
			loaderInfo.removeEventListener(ProgressEvent.PROGRESS, updateProgress);
			loaderInfo.removeEventListener(Event.COMPLETE, onComplete);

			var app:Class = getDefinitionByName("MyApp") as Class;
			addChild(new app(this));
		}
	}
}

Very important thing to notice here is, that your MainApp class instance does not have stage property available until its added on stage. So you can not access stage property directly in constructor but you have to define event handler for Event.ADDED_TO_STAGE.

Where to go from here:

The Flex Non-Docs

maashaack – ActionScript 3 framework, tools, libraries and utilities

AS3 Metadata Tags

Preloaders in AS3