Dynamisk inläsning av visningsinnehåll

Flash Player 9 och senare, Adobe AIR 1.0 och senare

Du kan läsa in någon av följande externa visningsresurser till ett program i ActionScript 3.0:

  • En SWF-fil som har skapats i ActionScript 3.0 – den här filen kan ha klassen Sprite, MovieClip eller någon annan klass som utökar Sprite. I AIR-program på iOS är det bara SWF-filer som inte innehåller ActionScript-bytekod som kan läsas in. Det innebär att SWF-filer som innehåller inbäddade data, t.ex. bilder och ljud, kan läsas in, men inte SWF-filer som innehåller körbar kod.

  • En bildfil – dessa är JPG-, PNG- och GIF-filer.

  • En AVM1 SWF-fil – detta är en SWF-fil skriven i ActionScript 1.0 eller 2.0. (stöds inte i AIR-mobilprogram)

Inläsning av resurserna görs via klassen Loader.

Inläsning av visningsobjekt

Loader-objekt används för att läsa in SWF-filer och grafikfiler till ett program. Klassen Loader är en underklass till klassen DisplayObjectContainer. Ett Loader-objekt kan innehålla endast ett underordnat visningsobjekt i sin visningslista – visningsobjektet som motsvarar SWF-filen eller grafikfilen som läses in. När du lägger ett Loader-objekt till visningslistan, som i nedanstående kod, kan du även lägga till det inlästa underordnade visningsobjektet till visningslistan efter inläsningen:

var pictLdr:Loader = new Loader(); 
var pictURL:String = "banana.jpg" 
var pictURLReq:URLRequest = new URLRequest(pictURL); 
pictLdr.load(pictURLReq); 
this.addChild(pictLdr);

När SWF-filen eller bilden är inläst kan du flytta visningsobjektet till en annan behållare för visningsobjekt, till exempel DisplayObjectContainer-objektet container i detta exempel:

import flash.display.*; 
import flash.net.URLRequest; 
import flash.events.Event; 
var container:Sprite = new Sprite(); 
addChild(container); 
var pictLdr:Loader = new Loader(); 
var pictURL:String = "banana.jpg" 
var pictURLReq:URLRequest = new URLRequest(pictURL); 
pictLdr.load(pictURLReq); 
pictLdr.contentLoaderInfo.addEventListener(Event.COMPLETE, imgLoaded);  
function imgLoaded(event:Event):void 
{ 
    container.addChild(pictLdr.content);  
}

Övervaka inläsningsförloppet

När filen har börjat läsas in skapas objektet LoaderInfo. Ett LoaderInfo-objekt innehåller information om inläsningsförloppet, inläsarens och utläsarens URL-adresser, det sammanlagda antalet byte för mediet samt mediets nominella höjd och bredd. Ett LoaderInfo-objekt skickar även händelser som övervakar förloppet av inläsningen.

I följande diagram visas hur LoaderInfo-objektet kan användas – för huvudklassinstansen i SWF-filen, för ett Loader-objekt och för ett objekt inläst via Loader-objektet:

Objektet LoaderInfo är tillgängligt som egenskap för både Loader-objektet och det inlästa visningsobjektet. Så snart inläsningen påbörjas blir LoaderInfo-objektet tillgängligt via egenskapen contentLoaderInfo i Loader-objektet. När visningsobjektet är inläst blir LoaderInfo-objektet tillgängligt även som egenskap för det inlästa visningsobjektet via egenskapen loaderInfo. Egenskapen loaderInfo för det inlästa visningsobjektet refererar till samma LoaderInfo-objekt som egenskapen contentLoaderInfo för Loader-objektet. Ett LoaderInfo-objekt delas m.a.o. mellan ett inläst objekt och det Loader-objekt som läste in det (mellan inläsare och utläsare).

För att få tillgång till egenskaper för inläst innehåll måste du lägga till en händelseavlyssnare till LoaderInfo-objektet enligt följande:

import flash.display.Loader; 
import flash.display.Sprite; 
import flash.events.Event; 
 
var ldr:Loader = new Loader(); 
var urlReq:URLRequest = new URLRequest("Circle.swf"); 
ldr.load(urlReq); 
ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, loaded); 
addChild(ldr); 
 
function loaded(event:Event):void 
{ 
    var content:Sprite = event.target.content; 
    content.scaleX = 2; 
}

Mer information finns i Hantera händelser.

Ange innehåll för inläsning

När du läser in en extern fil till Flash Player via metoderna load() eller loadBytes() i klassen Loader kan du välja att ange parametern context. Denna parameter är objektet LoaderContext.

Klassen LoaderContext innehåller tre egenskaper som du anger för att definiera hur inläst innehåll ska användas:

  • checkPolicyFile: Använd den här egenskapen endast när du läser in en bildfil (inte en SWF-fil). Om du anger egenskapen till true kontrolleras om det finns en principfil på den ursprungliga servern (se Webbplatsinställningar (principfiler)). Detta är endast nödvändigt för innehåll som kommer från andra domäner än den som SWF-filen med Loader-objektet kommer från. Om servern ger Loader-domänen tillstånd så kan ActionScript från SWF-filer i domänen få dataåtkomst till den inlästa bilden. Du kan m.a.o. använda kommandot BitmapData.draw() för att få åtkomst till data i den inlästa bilden.

    Observera att en SWF-fil från andra domäner än den som Loader-objektet kan anropa Security.allowDomain() för att tillåta en specifik domän.

  • securityDomain: Använd bara den här egenskapen när du läser in en SWF-fil (inte en bild). Ange den här för en SWF-fil från en annan domän än den som filen med Loader-objektet har. När du anger detta alternativ görs en sökning efter en korsdomänprincip och om sådan finns kan inläst SWF-innehåll korsskriptas av SWF-filer i de domäner som ges tillstånd med korsdomänprincipen. Du kan ange flash.system.SecurityDomain.currentDomain som denna parameter.

  • applicationDomain: Använd bara den här egenskapen när du läser in en SWF-fil som är skriven i ActionScript 3.0 (inte en bild eller SWF-fil som är skriven i ActionScript 1.0 eller 2.0). Vid inläsning av filen kan du ange att filen ska ingå i samma programdomän som Loader-objektet. Detta gör du genom att ange parametern applicationDomain med flash.system.ApplicationDomain.currentDomain. Genom att placera den inlästa SWF-filen i samma programdomän får du direktåtkomst till klasserna. Detta är praktiskt om du läser in en SWF-fil som innehåller inbäddade medier, som du får tillgång till via associerade klassnamn. Mer information finns i Arbeta med programdomäner.

Här är ett exempel på sökning efter en principfil vid inläsning av en bitmapp från en annan domän:

var context:LoaderContext = new LoaderContext(); 
context.checkPolicyFile = true; 
var urlReq:URLRequest = new URLRequest("http://www.[your_domain_here].com/photo11.jpg"); 
var ldr:Loader = new Loader(); 
ldr.load(urlReq, context);

Här visas ett exempel på sökning efter en principfil vid inläsning av en SWF-fil från en annan domän, för placering av filen i samma säkerhetssandlåda som Loader-objektet. Med koden läggs dessutom klasserna i den inlästa SWF-filen till i samma programdomän som Loader-objektet:

var context:LoaderContext = new LoaderContext(); 
context.securityDomain = SecurityDomain.currentDomain; 
context.applicationDomain = ApplicationDomain.currentDomain; 
var urlReq:URLRequest = new URLRequest("http://www.[your_domain_here].com/library.swf"); 
var ldr:Loader = new Loader(); 
ldr.load(urlReq, context);

Mer information finns i klassbeskrivningen för LoaderContext i Referenshandbok för ActionScript 3.0 i Adobe Flash-plattformen.

Läsa in SWF-filer i AIR for iOS

På iOS-enheter finns det begränsningar för inläsning och kompilering av kod vid körning. På grund av dessa begränsningar finns det vissa skillnader när det gäller hur externa SWF-filer läses in till programmet på sådana enheter:

  • Alla SWF-filer som innehåller ActionScript-kod måste inkluderas i programpaketet. Inga SWF-filer med kod kan läsas in från externa källor, till exempel via ett nätverk. Som en del av programpaketeringen kompileras all ActionScript-kod i alla SWF-filer i programpaketet till systemspecifik kod för iOS-enheter.

  • Det går inte att läsa in, ta bort och sedan läsa in en SWF-fil igen. Om du försöker göra det genereras ett fel.

  • Beteendet med att läsa in till minnet och sedan ta bort det därifrån är samma som på skrivbordsplattformar. Om du läser in en SWF-fil och sedan tar bort den tas alla visuella resurser som finns i SWF-filen bort från minnet. Däremot bevaras alla klassreferenser till ActionScript-klasser i den inläsa SWF-filen i minnet och dessa går att komma åt via ActionScript-koden.

  • Alla inlästa SWF-filer måste läsas in till samma programdomän som SWF-huvudfilen. Detta är inte standardbeteende, och därför måste du för varje SWF-fil som läses in skapa ett LoaderContext-objekt som anger huvudprogramdomänen och skicka det LoaderContext-objektet till Loader.load()-metodanropet. Om du försöker läsa in en SWF-fil till en annan programdomän än SWF-filens huvudprogramdomän genereras ett fel. Detta gäller även om den inlästa SWF-filen bara innehåller visuella resurser och ingen ActionScript-kod.

    Följande exempel visar den kod som används för att läsa in en SWF-fil från programpaketet till SWF-huvudfilens programdomän:

    var loader:Loader = new Loader(); 
    var url:URLRequest = new URLRequest("swfs/SecondarySwf.swf"); 
    var loaderContext:LoaderContext = new LoaderContext(false, ApplicationDomain.currentDomain, null); 
    loader.load(url, loaderContext);

En SWF-fil som bara innehåller resurser och ingen kod kan läsas in från programpaketet eller via ett nätverk. SWF-filen måste i båda fallen ändå läsas in till huvudprogramdomänen.

För tidigare AIR-versioner än AIR 3.6 rensas all kod ut från alla SWF-filer utom programmets SWF-huvudfil under kompileringen. SWF-filer som bara innehåller visuella resurser kan inkluderas i programpaketet och läsas in vid körning, men inte kod. Om du försöker läsa in en SWF-fil som innehåller ActionScript-kod genereras ett fel. En dialogruta med ett meddelande om ”Okompilerad ActionScript-kod” visas då i programmet.

Se även

Paketera och läsa in flera SWF-filer i AIR-program på iOS (på engelska)

Använda klasserna ProLoader och ProLoaderInfo

För att få hjälp med fjärranslutna delade bibliotek (RSL) introduceras klasserna fl.display.ProLoader och fl.display.ProLoaderInfo i Flash Professional CS5.5. Dessa klasser speglar klasserna flash.display.Loader och flash.display.LoaderInfo, men de ger ett mer konsekvent inläsningsbeteende.

Med ProLoader får du speciell hjälp med inläsning av SWF-filer där TLF (Text Layout Framework) med RSL-förinläsning används. Under körningen krävs för SWF-filer som förinläser andra SWF- eller SWZ-filer, till exempel TLF, en SWF-wrapperfil som endast är intern. Den extra komplexiteten som SWF-wrapperfilen innebär kan resultera i oönskade beteenden. ProLoader löser problemet genom att läsa in dessa filer som om de vore vanliga SWF-filer. Den lösningen som används i ProLoader-klassen är generell för användaren och kräver inga speciella åtgärder i ActionScript. Dessutom läser ProLoader in vanligt SWF-innehåll korrekt.

I Flash Professional CS 5.5 och senare är det säkert att ersätta all användning av Loader-klassen med ProLoader-klassen. Exportera sedan programmet till Flash Player 10.2 eller senare så att ProLoader får åtkomst till nödvändiga ActionScript-funktioner. Du kan även använda ProLoader för tidigare versioner av Flash Player som har stöd för ActionScript 3.0. Du får emellertid ut maximalt av ProLoader-funktionerna endast med Flash Player 10.2 eller senare. Använd alltid ProLoader när du använder TLF i Flash Professional CS5.5 eller senare. Det finns inget behov av ProLoader i andra miljöer än Flash Professional.

Viktigt! För SWF-filer som publiceras i Flash Professional CS5.5 och senare, kan du alltid använda klasserna fl.display.ProLoader och fl.display.ProLoaderInfo i stället för flash.display.Loader och flash.display.LoaderInfo.

Problem åtgärdade med klassen ProLoader

ProLoader-klassen åtgärdar problem som den äldre Loader-klassen inte kunde hantera. Dessa problem har att göra med RSL-förinläsning av TLF-bibliotek. Det gäller speciellt för SWF-filer som använder ett Loader-objekt för att läsa in andra SWF-filer. Bland annat åtgärdas följande problem:

  • Skripthantering mellan den inläsande och den inlästa filen sker inte så som förväntat. Klassen ProLoader anger automatiskt den inläsande SWF-filen som överordnad till den inlästa SWF-filen. Kommunikationen sker sålunda från den inläsande SWF-filen direkt till den inlästa SWF-filen.

  • SWF-programmet måste aktivt hantera inläsningsprocessen. För detta krävs att fler händelser implementeras, till exempel added, removed, addedToStage och removedFromStage. Om ditt program är avsett för Flash Player 10.2 eller senare, tar ProLoader bort behovet att detta extraarbete.

Uppdatera kod för att använda ProLoader i stället för Loader

Eftersom ProLoader speglar klassen Loader kan du enkelt växla klasserna i din kod. I följande exempel visas hur befintlig kod uppdateras för att använda den nya klassen:

import flash.display.Loader; 
import flash.events.Event; 
var l:Loader = new Loader(); 
 
addChild(l); 
l.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComplete); 
l.load("my.swf"); 
function loadComplete(e:Event) { 
    trace('load complete!'); 
}

Den här koden kan uppdateras för att använda ProLoader enligt följande:

import fl.display.ProLoader; 
import flash.events.Event; 
var l:ProLoader = new ProLoader(); 
 
addChild(l); 
l.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComplete); 
l.load("my.swf"); 
function loadComplete(e:Event) { 
    trace('load complete!'); 
}