I have run into a very strange problem with Flash and Flex. It appears that under certain circumstances, movie clips from a SWF loaded at runtime (using Loader) cannot be instantiated if another SWF has been loaded in the mean time. Here is the complete code for a program that reproduces the error. It is compiled using mxmlc, via Ensemble Tofino:
package
{
import flash.display.*;
import flash.events.*;
import flash.net.*;
import flash.system.*;
public class DynamicLoading extends Sprite
{
private var testAppDomain:ApplicationDomain;
public function DynamicLoading()
{
var request:URLRequest = new URLRequest("http://localhost/content/test.swf");
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onTestLoadComplete);
loader.load(request);
}
private function onTestLoadComplete(e:Event):void
{
var loaderInfo:LoaderInfo = LoaderInfo(e.target);
testAppDomain = loaderInfo.applicationDomain;
// To get the error, uncomment these lines...
//var request:URLRequest = new URLRequest("http://localhost/content/tiny.swf");
//var loader:Loader = new Loader();
//loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onTinyLoadComplete);
//loader.load(request);
// ...and comment this one:
onTinyLoadComplete();
}
private function onTinyLoadComplete(e:Event = null):void
{
var spriteClass:Class = Class(testAppDomain.getDefinition("TopSymbol"));
var sprite:Sprite = Sprite(new spriteClass());
sprite.x = sprite.y = 200;
addChild(sprite);
}
}
}
With the second loading operation commented out as shown above, the code works. However, if the second loading operation is uncommented and onTinyLoadComplete runs after the second SWF is loaded, the line containing new spriteClass()
fails with the following exception:
TypeError: Error #1034: Type Coercion failed: cannot convert flash.display::MovieClip@2dc8ba1 to SubSymbol. at flash.display::Sprite/constructChildren() at flash.display::Sprite() at flash.display::MovieClip() at TopSymbol() at DynamicLoading/onTinyLoadComplete()[C:\Users\...\TestFlash\DynamicLoading.as:38]
test.swf and tiny.swf were created in Flash CS4. test.swf contains two symbols, both exported for ActionScript, one called TopSymbol and one called SubSymbol. SubSymbol contains a simple graphic (a scribble) and TopSymbol contains a single instance of SubSymbol. tiny.swf contains nothing; it is the result of publishing a new, empty ActionScript 3 project.
If I modify test.swf so that SubSymbol is not exported for ActionScript, the error goes away, but in our real project we need the ability to dynamically load sprite classes that contain other, exported sprite classes as children.
Any ideas as to what is causing this, or how to fix it?
Edit: A couple of people have suggested that tiny.swf may contain a class with the same name as a class from test.swf or the parent (DynamicLoading.swf). It does not. As I said above, I created tiny.swf myself by simply publishing a brand-new, empty Flash CS4 project. Here is the complete output of swfdump -D
when run on tiny.swf:
[HEADER] File version: 10 [HEADER] File is zlib compressed. Ratio: 41% [HEADER] File size: 1343 [HEADER] Frame rate: 30.000000 [HEADER] Frame count: 1 [HEADER] Movie width: 550.00 [HEADER] Movie height: 400.00 [045] 4 FILEATTRIBUTES as3 symbolclass [04d] 1284 METADATA [009] 3 SETBACKGROUNDCOLOR (ff/ff/ff) [056] 11 SCENEDESCRIPTION [001] 0 SHOWFRAME 1 (00:00:00,000) [000] 0 END