Utilisation de domaines d’application

Flash Player 9 et les versions ultérieures, Adobe AIR 1.0 et les versions ultérieures

Le rôle de la classe ApplicationDomain est de stocker un tableau des définitions ActionScript 3.0. L’ensemble du code d’un fichier SWF est défini de sorte à exister dans un domaine d’application. Les domaines d’application servent à partitionner les classes qui se trouvent dans un même domaine de sécurité. Ainsi, plusieurs définitions de la même classe peuvent exister et les enfants peuvent réutiliser les définitions des parents.

Vous pouvez faire appel aux domaines d’application lors du chargement, au moyen de l’API de la classe Loader, d’un fichier SWF externe écrit en ActionScript 3.0 (Notez que vous ne pouvez pas utiliser les domaines d’application lorsque vous chargez une image ou un fichier SWF écrit en ActionScript 1.0 ou 2.0.) Toutes les définitions ActionScript 3.0 contenues dans la classe chargée sont stockées dans le domaine d’application. Lorsque vous chargez un fichier SWF, vous devez indiquer que le fichier doit être inclus dans le même domaine d’application que l’objet Loader en attribuant au paramètre applicationDomain de l’objet LoaderContext la valeur ApplicationDomain.currentDomain. Si vous placez le fichier SWF chargé dans le même domaine d’application, vous pourrez accéder directement à ses classes, Cela s’avère pratique si vous chargez un fichier SWF qui contient des médias incorporés auxquels vous pouvez accéder via les noms de classe associés, ou si vous voulez accéder aux méthodes du fichier SWF chargé.

L’exemple suivant présuppose l’accès à un fichier Greeter.swf distinct définissant une méthode publique nommée welcome() :

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 
        { 
            var myGreeter:Class = ApplicationDomain.currentDomain.getDefinition("Greeter") as Class; 
            var myGreeter:Greeter = Greeter(event.target.content); 
            var message:String = myGreeter.welcome("Tommy"); 
            trace(message); // Hello, Tommy 
        } 
    } 
}

Voir aussi l’exemple de classe ApplicationDomain dans le manuel Guide de référence ActionScript 3.0 pour la plate-forme Adobe Flash.

Voici d’autres points à garder à l’esprit lorsque vous utilisez les domaines d’application :

  • L’ensemble du code d’un fichier SWF est défini de sorte à exister dans un domaine d’application. L’application principale s’exécute dans le domaine d’application actif. Le domaine du système contient tous les domaines d’application, y compris le domaine actif ; il contient donc toutes les classes Flash Player.

  • A l’exception du domaine du système, tous les domaines d’application sont associés à un domaine parent. Le domaine parent du domaine de l’application principale est le domaine du système. Les classes chargées ne sont définies que si leur parent ne les définit pas encore. Vous ne pouvez pas remplacer une définition de classe chargée par une définition plus récente.

Le schéma suivant illustre une application qui charge du contenu à partir de divers fichiers SWF au sein d’un domaine unique, domain1.com. Selon le contenu chargé, différents domaines d’application peuvent être utilisés. Le texte suivant décrit la logique utilisée pour définir le domaine d’application approprié pour chaque fichier SWF de l’application.

Afficher le graphique en taille réelle
A.
Utilisation A

B.
Utilisation B

C.
Utilisation C

Le fichier principal d’application est application1.swf. Il contient des objets Loader qui chargent du contenu à partir d’autres fichiers SWF. Dans ce scénario, le domaine d’application 1 est actif. Utilisation A, Utilisation B et Utilisation C illustrent les différentes techniques permettant de définir le domaine d’application approprié pour chaque fichier SWF de l’application.

Utilisation A
Partitionnez le fichier SWF enfant en créant un enfant du domaine du système. Dans le schéma, le domaine d’application 2 est créé en tant qu’enfant du domaine du système. Le fichier application2.swf est chargé dans le domaine d’application 2 et ses définitions de classe sont ainsi partitionnées à partir des classes définies dans application1.swf.

Cette technique s’appliquera par exemple lorsqu’une ancienne application doit charger dynamiquement une nouvelle version de la même application sans créer de conflits. Les conflits sont éliminés parce que même si les noms de classe sont les mêmes, ils sont répartis dans différents domaines d’application.

Le code suivant crée un domaine d’application qui est un enfant du domaine du système, puis commence à charger un fichier SWF à l’aide de ce domaine d’application :

var appDomainA:ApplicationDomain = new ApplicationDomain(); 
 
var contextA:LoaderContext = new LoaderContext(false, appDomainA); 
var loaderA:Loader = new Loader(); 
loaderA.load(new URLRequest("application2.swf"), contextA);

Utilisation B
Ajoutez de nouvelles définitions de classe aux définitions actuelles. Le domaine d’application de module1.swf est défini sur le domaine actif (Domaine d’application 1). Vous pouvez alors ajouter au jeu actuel de définitions de classe de l’application de nouvelles définitions de classe. Cela pourrait servir pour une bibliothèque d’exécution partagée appartenant à l’application principale. Le fichier SWF est traité comme une bibliothèque partagée distante (RSL, remote shared library). Utilisez cette technique pour charger des RSL à l’aide d’un fichier de préchargement avant le lancement de l’application.

Le code suivant charge un fichier SWF, en définissant son domaine d’application sur le domaine actif :

var appDomainB:ApplicationDomain = ApplicationDomain.currentDomain; 
 
var contextB:LoaderContext = new LoaderContext(false, appDomainB); 
var loaderB:Loader = new Loader(); 
loaderB.load(new URLRequest("module1.swf"), contextB);

Utilisation C
Utilisez les définitions de classe du parent en ajoutant un nouveau domaine enfant au domaine actif. Le domaine d’application de module3.swf est un enfant du domaine actif, qui utilise pour toutes les classes les versions du parent. Cette technique peut s’appliquer à un module d’une application Internet riche (RIA, Rich Internet Application) à plusieurs écrans, qui serait chargé comme enfant de l’application principale et utiliserait les types de cette dernière. Si vous pouvez garantir que toutes les classes sont toujours mises à jour pour rester compatibles avec les anciennes versions et que l’application de chargement est toujours plus récente que les contenus qu’elle charge, les enfants utiliseront les versions des parents. L’utilisation d’un nouveau domaine d’application permet également de décharger toutes les définitions de classe en vue du nettoyage, à condition de veiller à ce qu’il ne subsiste aucune référence au fichier SWF enfant.

Cette technique autorise les modules chargés à partager les objets Singleton et les membres de classe statiques de l’objet Loader.

Le code suivant crée un domaine enfant dans le domaine actif et commence à charger un fichier SWF à l’aide de ce domaine d’application :

var appDomainC:ApplicationDomain = new ApplicationDomain(ApplicationDomain.currentDomain); 
 
var contextC:LoaderContext = new LoaderContext(false, appDomainC); 
var loaderC:Loader = new Loader(); 
loaderC.load(new URLRequest("module3.swf"), contextC);