View comments | RSS feed

Using the ApplicationDomain class

The purpose of the ApplicationDomain class is to store a table of ActionScript 3.0 definitions. All code in a SWF file is defined to exist in an application domain. You use application domains to partition classes that are in the same security domain. This allows multiple definitions of the same class to exist and also lets children reuse parent definitions.

You can use application domains when loading an external SWF file written in ActionScript 3.0 using the Loader class API. (Note that you cannot use application domains when loading an image or SWF file written in ActionScript 1.0 or ActionScript 2.0.) All ActionScript 3.0 definitions contained in the loaded class are stored in the application domain. When loading the SWF file, you can specify that the file be included in the same application domain as that of the Loader object, by setting the applicationDomain parameter of the LoaderContext object to ApplicationDomain.currentDomain. By putting the loaded SWF file in the same application domain, you can access its classes directly. This can be useful if you are loading a SWF file that contains embedded media, which you can access via their associated class names, or if you want to access the loaded SWF file's methods, as shown in the following example:

package
{
    import flash.display.Loader;
    import flash.display.Sprite;
    import flash.events.*;
    import flash.net.URLRequest;
    import flash.system.ApplicationDomain;
    import flash.system.LoaderContext;

    public class ApplicationDomainExample extends Sprite
    {
        private var ldr:Loader;
        public function ApplicationDomainExample()
        {
            ldr = new Loader();
            var req:URLRequest = new URLRequest("Greeter.swf");
            var ldrContext:LoaderContext = new LoaderContext(false, ApplicationDomain.currentDomain);
            ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
            ldr.load(req, ldrContext);    
        }
        private function completeHandler(event:Event):void
        {
            ApplicationDomain.currentDomain.getDefinition("Greeter");
            var myGreeter:Greeter = Greeter(event.target.content);
            var message:String = myGreeter.welcome("Tommy");
            trace(message); // Hello, Tommy
        }
    }
}

Other things to keep in mind when you work with application domains include the following:

The following diagram shows an application that loads content from various SWF files within a single domain, domain1.com. Depending on the content you load, different application domains can be used. The text that follows describes the logic used to set the appropriate application domain for each SWF file in the application.


Diagram showing uses of different application domains for SWFs loaded by an application. application1.swf loads module1.swf, both in application domain 1. It also loads module2.swf, in application domain 3, and application2.swf in application domain 2.

The main application file is application1.swf. It contains Loader objects that load content from other SWF files. In this scenario, the current domain is Application domain 1. Usage A, usage B, and usage C illustrate different techniques for setting the appropriate application domain for each SWF file in an application.

Usage A: Partition the child SWF file by creating a child of the system domain. In the diagram, Application domain 2 is created as a child of the system domain.The application2.swf file is loaded in Application domain 2, and its class definitions are thus partitioned from the classes defined in application1.swf.

One use of this technique is to have an old application dynamically loading a newer version of the same application without conflict. There is no conflict because although the same class names are used, they are partitioned into different application domains.

The following code creates an application domain that is a child of the system domain:

request.url = "application2.swf";
request.applicationDomain = new ApplicationDomain();

Usage B: Add new class definitions to current class definitions. The application domain of module1.swf is set to the current domain (Application domain 1). This lets you add to the application's current set of class definitions with new class definitions. This could be used for a run-time shared library of the main application. The loaded SWF is treated as a remote shared library (RSL). Use this technique to load RSLs by a preloader before the application starts.

The following code sets an application domain to the current domain:

request.url = "module1.swf";
request.applicationDomain = ApplicationDomain.currentDomain;

Usage C: Use the parent's class definitions by creating a new child domain of the current domain. The application domain of module3.swf is a child of the current domain, and the child uses the parent's versions of all classes. One use of this technique might be a module of a multiple-screen rich Internet application (RIA), loaded as a child of the main application, that uses the main application's types. If you can ensure that all classes are always updated to be backward compatible, and that the loading application is always newer than the things it loads, the children will use the parent versions. Having a new application domain also allows you to unload all the class definitions for garbage collection, if you can ensure that you do not continue to have references to the child SWF.

This technique lets loaded modules share the loader's singleton objects and static class members.

The following code creates a new child domain of the current domain:

request.url = "module3.swf";
request.applicationDomain = new ApplicationDomain(ApplicationDomain.currentDomain);

Flash CS3


Comments


greg_spencer said on Jun 26, 2007 at 12:31 PM :
What does the code for the Greeter.swf file look like? That would make it clear why you have to pass the content pointer from the loader, and what type that content object is.
galtdagny said on Jul 6, 2007 at 1:29 PM :
I agree with Greg. I have been trying for two weeks to access objects in a
called swf with no luck. The example does not let me see Greeter.swf so I
can tie the whole thing together and understand what is being done.

I simply want to access a named movie clip instance in a loaded swf.
No screen name said on Jul 19, 2007 at 3:15 PM :
These examples do not make sense. What object can you assign url and applicationDomain to? URLRequest is logical place for the "url" but it does not allow ".applicationDomain" property

Need more explanation here. Usage C does not work for me which ever way you try it
No screen name said on Sep 10, 2007 at 6:42 PM :
// child SWF uses parent domain definitions
// if defined there, otherwise its own
var childDefinitions:LoaderContext = new LoaderContext();
childDefinitions.applicationDomain = new ApplicationDomain(ApplicationDomain.currentDomain);

// child SWF adds its unique definitions to
// parent SWF; both SWFs share the same domain
// child SWFs definitions do not overwrite parents
var addedDefinitions:LoaderContext = new LoaderContext();
addedDefinitions.applicationDomain = ApplicationDomain.currentDomain;

// child SWF domain is completely separate and
// each SWF uses its own definitions
var separateDefinitions:LoaderContext = new LoaderContext();
separateDefinitions.applicationDomain = new ApplicationDomain();

// set loader context in load()
myLoader.load(request, separateDefinitions);

c/o senocular
DaddyDog1 said on Nov 8, 2007 at 10:10 PM :
When I access the event.content.taget I get a SystemManager for the flex application which I am loading, but inside the application is null and there are no usable children. How can I access the child application?
vinnyguido said on Jan 8, 2008 at 5:55 AM :
Accessing the variables and methods of a loaded swf.
I don't know if this is the correct place for this or not, but here is a simple example of one swf file loading in another swf file and then accessing the second swf's content.
The first class/package listing below is the Document Class of the Main swf and the second class/package listing is the Document Class of the Secondary swf file. Make sure you compile the secondary swf before you compile and run the main application.



/////////////////////////////////////////////////////////////////////////////////////////////////////////
package
{
import flash.display.Sprite;
import flash.events.*;
import flash.net.URLRequest;
import flash.display.Loader;

public class MainApp extends Sprite
{
public var url:URLRequest;
public var ldr:Loader;

public function MainApp()
{
trace("inside MainApp()");

url = new URLRequest("SecondarySWF.swf");
ldr = new Loader();
configureListeners(ldr.contentLoaderInfo);

ldr.load(url);
addChild(ldr);
}

private function configureListeners(dispatcher:IEventDispatcher):void {
dispatcher.addEventListener(Event.COMPLETE, completeHandler);
dispatcher.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
}

private function completeHandler(event:Event):void {
trace("completeHandler: " + event);
event.target.content.init_map();
trace("title = [" + event.target.content.title + "]" );
}

private function ioErrorHandler(event:IOErrorEvent):void {
trace("ioErrorHandler: " + event);
}
}
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
package
{
import flash.display.Sprite;
import flash.display.Shape;

public class TheMap extends Sprite
{
public var title:String;
public var shp:Shape;

public function TheMap(t:String = "TITLE")
{
trace("inside TheMap()");
title = t;

shp = new Shape();
shp.graphics.beginFill(0xaaaaff);
shp.graphics.drawRect(10,10, 400, 400);
shp.graphics.endFill();
addChild(shp);
}

public function init_map()
{
trace("inside init_map()");
}
}
}
/////////////////////////////////////////////////////
Good luck,
Vinny
vinnyguido said on Jan 8, 2008 at 7:13 AM :
Here's a simple example of the Greeting.as file. This should be the Document class of the Greeting.fla file. Make sure to compile this class before compiling and running the main fla file with the code shown above.

//////////////////////////////////////////////////////////////////////////////
package
{
import flash.display.Sprite;

public class Greeter extends Sprite
{
public function Greeter(o:Object = null)
{
trace("inside Greeter(" + o + ")");
}

public function welcome(s:String)
{
trace("inside welcome(s=" + s + ")" );
return "Hello" + s;
}
}
}
//////////////////////////////////////////////////////////////////////
Vinny
cheesewiz1982 said on Oct 19, 2008 at 8:25 AM :
getDefinition requires a full qualified classname (e.g: "classes.Test" instead of "Test")

Might help someone.

 

RSS feed | Send me an e-mail when comments are added to this page | Comment Report

Current page: http://livedocs.adobe.com/flash/9.0/main/00000327.html