Bypassing the Flex Preloader

Ahh, one of those holy grail type posts. After days of searching to answer a problem, I’ve managed to solve it by completely bypassing the preloader in Flex. It can be done, and here’s how:

Flex uses a 2-frame configuration to display its content. The Preloader is put on the first frame, and is downloaded immediately. It then waits for the rest of the content to load and fires its complete event. Then the SystemManager jumps to frame 2 and everything’s ready to go. To turn this off, we need to do two things:

1: Create a preloader shim file named PreloaderShim.as:

package
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.TimerEvent;
	import flash.utils.Timer;
 
	import mx.managers.SystemManager;
	import mx.preloaders.DownloadProgressBar;
 
	public class PreloaderShim extends DownloadProgressBar
	{
		private var delay:Timer = new Timer(1);
 
		override public function set preloader(value:Sprite):void
		{
			SystemManager(value.parent).gotoAndStop(2);
			delay.addEventListener(TimerEvent.TIMER, go);
			delay.start();
		}
 
		public function go(e:TimerEvent):void{
			delay.stop();
			delay.removeEventListener(TimerEvent.TIMER, go);
			delay = null;
			dispatchEvent(new Event(Event.COMPLETE));
		}
 
	}
}

2: Use this in our Flex file:

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
				preloader="PreloaderShim">

We override the set preloader function of the DownloadProgressBar class. This is automatically set to the preloader instance in Flex. This instance’s parent is the SystemManager. The SystemManager has a gotoAndStop method that allows us to skip to the next frame. Almost immediately, we can fire the complete event. I think that Flex needs a single millisecond to begin its download process, so we wait that long before firing the complete. After that, Flex loads, no preloader perceived.

The Flex part is easy–just point your Flex project to have this new class as a preloader. Just drop your PreloaderShim.as file in with your mxml files and you’re off and running!

Note, I’ve only tried this on local files, and have NO idea how it would work in a real, downloading production file. It works fine for me, but please test it before you go breaking things.

Flash IDE CS4 crashes on any AS3 file close after profiling in Eclipse FlexBuilder 3

Recently I felt the need to work with the Flex Builder 3 Profiler. I found, as many OSX people do that the profiler didn’t work out of the box. I modified my mm.cfg file with the following line

PreloadSwf=/Users/mengel/Documents/workspace/.metadata/.plugins/
	com.adobe.flash.profiler/ProfilerAgent.swf?host=127.0.0.1&port=9999

This allowed the profiler to talk to pretty much every swf I load and was working great. What I didn’t know is that when you get your profiler working, it starts modifying your Flash Player preferences in a way that the Flash IDE may not like. It specifically added a folder:

/Users/mengel/Library/Preferences/Macromedia/Flash Player/#Security

This folder, coupled with my project settings, produced a configuration file that, every time I closed anything remotely AS3 related, crashed Flash, never to return. Since this is a bug in Flash player, uninstalling/reinstalling CS4 does nothing.
Even opening the projects panel and closing it breaks Flash as the IDE uses the player to display it. The solution is to remove the #security folder, drop your mm.cfg, and work without the profiler until you absolutely need it.

A friend of mine also tells me that the beta of FlashBuilder 4 may solve this problem as well. Your mileage may vary.

Send a Tweet from Flash/Flex

I’ve played with all of the Twitter API systems out there, and I find them bulky and unpleasant to instantiate. If all you want to do is send a tweet from a flash project, this is the method you need.

Note: You’ll need a copy of the Base64 Class, which is available here or in the link below (This is excellent work, by the way).

import com.dynamicflash.util.Base64;
 
public function sendTweet(username:String, password:String, text:String):void
{
	var urlRequest:URLRequest = new URLRequest('http://api.twitter.com/1/statuses/update.xml');
	var urlLoader:URLLoader = new URLLoader();
 
	var vars:URLVariables = new URLVariables();
	vars.status = text.substr(0, 140);
 
	urlRequest.method = URLRequestMethod.POST;
	urlRequest.data = vars;
 
	urlRequest.requestHeaders = [new URLRequestHeader("Authorization", "Basic " + Base64.encode(username + ":" + password))];
 
	urlLoader.load(urlRequest)
}

If you pass a valid username, password, and string to this method, it should update the status to what you specify.

Finally, you’ll need to create a crossdomain.xml file for use with Twitter otherwise you’ll get security exceptions. If you want to test the functionality, you can run the SWF outside the HTML file, which doesn’t require the same security settings or you can add your project folder to the allowed list of sites using the Settings Manager (I usually add my whole hard drive to this — ‘c:\” or “/” on a Mac).

Custom UI for Flash Components – Part 4 – Prepping your UI

Part 1|Part 2|Part 3|Part 4
Flex Project File
UPDATE: You will also have to implement one last step: bypassing the flex preloader in order to make this work.

Now that our component is ready, we use the TextField in out Flex project to indicate the current state of the Flash component.

As far as I know, there’s no way of determining which variables are Inspectable in our MyComponent class. This means we have to hard code the resulting variables in Flex as well.

Update our flex Application to the following:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
				layout="absolute"
				creationComplete="init()">
	<mx:Script>
		<![CDATA[
			import adobe.utils.MMExecute;
 
			public function init():void
			{
				buttonLabel.text = MMExecute("fl.getDocumentDOM().selection[0].parameters['buttonLabel'].value");
			}
 
			public function updateParams():void
			{
				MMExecute("fl.getDocumentDOM().selection[0].parameters['buttonLabel'].value = '" + buttonLabel.text + "'");
			}
		]]>
	</mx:Script>
 
	<mx:TextInput id="buttonLabel"
				  change="updateParams()"/>
</mx:Application>

First, we call init() when the Application is done instantiating.
This uses JSFL to retrieve the “buttonLabel” parameter of the selected item on the stage. This will always be your component because it will only show this UI when the component (and only this component) is selected.
It then sets the text attribute of the TextInput to the buttonLabel parameter.
Finally, we’ve set a listener to the change Event of the buttonLabel TextInput that calls the upddateParams() function.
The updateParams sets the buttonLabel parameter of the selected item in Flash to the value of the text attribute of the buttonLabel TextField. This update will happen every time you change the textField, so it will in effect be realtime.

Build your Project again by choosing Build Project from the Project Menu and you’re done. When you drag an instance of your component onto the Stage, the Component Inspector should begin with the default text and if you change it, it should then stick.

UPDATE: You will also have to implement one last step: bypassing the flex preloader in order to make this work.
Part 1|Part 2|Part 3|Part 4
Flex Project File

Custom UI for Flash Components – Part 2 – Creating your component

Part 1|Part 2|Part 3|Part 4
Flex Project File
Create a new Flash file called Components and save it into the src directory of your MyComponentUI Flex Project.
Create a new as file named MyComponent.as and save it in the same folder as the FLA.
Paste the following code in your MyComponent.as file:

package
{
	import flash.display.MovieClip;
 
	public class MyComponent extends MovieClip
	{
		public function MyComponent()
		{
			super();
		}
 
	}
}

In the Flash IDE, create a new symbol of type MovieClip with a dynamic TextField with an instance name of buttonLabel.

Right click the symbol in your library and go to the properties.

If necessary, click the advanced button to display the Linkage section.

Check the box marked Export for ActionScript.

Hit OK.

We’ve now created a library symbol that has a TextField named buttonLabel
Part 1|Part 2|Part 3|Part 4
Flex Project File

Custom UI for Flash Components – Part 1 – Creating your UI

Part 1|Part 2|Part 3|Part 4
Flex Project File
This is the first in a multi-part series. I wish I could make this simpler, but the lack of documentation on how to do this properly let alone how to do it at all is astounding. I used Flex to create my UI, but any AS3 UI should work. This tutorial will use Flex:
Create a new Flex Project and name it MyComponentUI
Use the following code for your Application

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
				layout="absolute">
	<mx:TextInput id="buttonLabel"/>
</mx:Application>

Now, build your project by choosing Build Project from the Project menu.

All we’ve done is create a basic Flex Application with a single TextField named buttonLabel.
Part 1|Part 2|Part 3|Part 4
Flex Project File

Building AS3 Using ANT Scripts

I spent a good chunk of time finding the simplest ANT build script I could and using it to compile my simple AS3 project. This is a simple as it gets:

<project name="build" default="compile">
	<property file="${ant.home}/path.properties"/>
	<taskdef resource="flexTasks.tasks" />
	<target name="compile">
		<mxmlc file="src/AntTest.as" output="bin-debug/AntTest.swf"/>
	</target>
</project>

The project name attribute is up to you.
The default is the target to be run if you just type “ant”
The first property sets basic ANT properties
The taskdef includes Flex-specific information
The target name allows you to reference this action elsewhere in the build file
The mxmlc file is the source for the compiler
The mxmlc output is the output for the compiler
Just replace the as file and swf file with your specific filenames, open up the terminal, browse to the project dir, and type ant
it should produce a swf for you.

clAir – alpha – a Craigslist aggregator in Adobe Air

I’ve been working on a little side project for a while to be able to view multiple Craigslist results pages at once. To make this happen, I’ve built a basic app in PHP, but I thought it would be significantly nicer to build something standalone and FAST. I tried Flex, but the security sandbox was a pain, as was a lack of useful features, so here we go! Please leave feedback and bugs, if you find them.
clair1

Adding an AS3 Sprite to an MXML file

Recently, working on an FLV component, I tried to add a sprite to an MXML component. Since UIComponent inherits Sprite, it’s too high up to be added to the stage. What you CAN do, though, is add the sprite to a UIComponent component in MXML and display it that way.

I’ve used the As3FLV component I wrote in this example. the As3FLV extends sprite, so all we have to do is add it to the UIComponent I’ve created in MXML and it should show up. I’ve also built the As3FLV component to resize itself based on the parent size etc.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
				layout="absolute"
				xmlns:local="*"
				xmlns:net="flash.net.*"
				width="100%"
				height="100%"
				creationComplete="init();">
	<mx:Script>
		<![CDATA[
			import com.MEMD.As3FLV;
			private var flv:As3FLV = new As3FLV();
 
			public function init():void
			{
				flv.source = "http://www.mediacollege.com/video-gallery/testclips/20051210-w50s.flv";
				holder.addChild(flv);
			}
		]]>
	</mx:Script>
	<mx:UIComponent id="holder"
					width="100%"
					height="100%"/>
</mx:Application>

From the top: creationComplete=”init();” – runs the init function at the beginning
import com.MEMD.As3FLV; – imports this class
private var flv:As3FLV = new As3FLV(); – creates a variable named “flv” as an instance of As3FLV
flv.source = “http://www.mediacollege.com/video-gallery/testclips/20051210-w50s.flv”; – sets the source of “flv” to a sample FLV
holder.addChild(flv); – adds our instance to the UIComponent below
width=”100%” height=”100%” – sets the width and height of the component to 100% of the container.

I’ve also attached a copy of a project below. I hope it helps.