The Flash Player 8.5 features a nifty API to dynamically load assets at runtime, using the flash.display.Loader
and flash.system.ApplicationDomain
classes. Let’s assume we have a package, test.c1
, that we want to keep in a separate SWF and only load it into the main SWF when needed.
We create a project Main that has the following structure:
Main.as
Child1.as
test/c1/TestClass.as
Child1.as
is compiled into Child1.swf
and contains test.c1.TestClass
.
Main.as
is our main application class that loads Child1.swf
and uses test.c1.TestClass
.
test/c1/TestClass.as
package test.c1 { public class TestClass { public function TestClass() { } public function method():String { return 'test.c1.TestClass.method()'; } } }
Child1.as
package { import flash.display.Sprite; import test.c1.TestClass; public class Child1 extends Sprite { public var TestClassInst:TestClass; public function Child1() { } } }
Main.as
package { import flash.display.Sprite; import flash.display.Loader; import flash.system.ApplicationDomain; import flash.net.URLRequest; import flash.events.*; import flash.util.trace; public class Main extends Sprite { private var child1:Loader; public function Main() { var url1:URLRequest = new URLRequest('Child1.swf'); url1.applicationDomain = new ApplicationDomain(ApplicationDomain.currentDomain); child1 = new Loader(); child1.addEventListener(EventType.COMPLETE, onChild1Complete); child1.load(url1); } private function onChild1Complete(e:Event):Void { trace('onChild1Complete ' + e); var c:Class = child1.loadeeInfo.applicationDomain.getClass('test.c1.TestClass'); var co:Object = new c(); trace('test.c1.TestClass.method() returns: ' + co.method()); } } }
Using this method we could have different implementations of an API in different SWFs, and load the one we need at runtime. Naturally, we would want to use interfaces to ensure the API implements the right things, and use those interfaces for both the external modules and the main app. Note that i instantiate test.c1.TestClass
as an anonymous object in the above example (var co:Object = new c();
). I actually should have provided an interface definition test.ITestClass
that describes the features of that external class (var co:ITestClass = new c();
), however the alpha of Flex Builder has a bug that currently prevents us from doing so. Macromedia is aware of that bug so hopefully this is fixed soon.