Dynamiczne ładowanie treści wyświetlanych

Flash Player 9 i nowsze wersje, Adobe AIR 1.0 i nowsze wersje

Do aplikacji ActionScript 3.0 można załadować dowolne z poniższych zasobów wyświetlanych:

  • Plik SWF utworzony w języku ActionScript 3.0 — plik może zawierać klasę Sprite, MovieClip lub dowolną inna klasę, która rozszerza klasę Sprite. W aplikacjach AIR w systemie iOS można wczytywać wyłącznie pliki SWF, które nie zawierają kodu bajtowego ActionScript. Oznacza to, że można wczytywać pliki SWF zawierające osadzone dane, takie jak obrazy i dźwięk, ale nie pliki SWF zawierające kod wykonywalny.

  • Plik obrazu — pliki: JPG, PNG i GIF.

  • Plik AVM1 SWF — plik SWF zapisany w języku ActionScript 1.0 lub 2.0. (Ten format nie jest obsługiwany w aplikacjach AIR dla urządzeń przenośnych).

Do ładowania tych zasobów służy klasa Loader.

Ładowanie obiektów wyświetlanych

Obiekty Loader służą do ładowania plików SWF i plików graficznych do aplikacji. Klasa Loader jest podklasą klasy DisplayObjectContainer. Lista wyświetlania obiektu Loader może zawierać tylko jeden podrzędny obiekt wyświetlany — obiekt wyświetlany reprezentujący ładowany plik SWF lub plik graficzny. Dodanie obiektu Loader do listy wyświetlania, jak w poniższym kodzie, powoduje również dodanie ładowanego podrzędnego obiektu wyświetlanego (po załadowaniu) do tej listy wyświetlania:

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

Po załadowaniu pliku SWF lub obrazu możliwe jest przesunięcie załadowanego obiektu wyświetlanego do innego kontenera obiektu wyświetlanego, takiego jak obiekt container DisplayObjectContainer w tym przykładzie:

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);  
}

Monitorowanie postępu ładowania

Po rozpoczęciu ładowania pliku następuje utworzenie obiektu LoaderInfo. Obiekt LoaderInfo zawiera informacje, takie jak postęp ładowania, adresy URL modułu ładującego i treści ładowanej, sumaryczna liczba bajtów dla nośnika, a także nominalna wysokość i szerokość nośnika. Obiekt LoaderInfo wywołuje również zdarzenia dla monitorowania postępu ładowania.

Poniższy schemat prezentuje różne zastosowania obiektu LoaderInfo — dla instancji głównej klasy pliku SWF, dla obiektu Loader oraz dla obiektu załadowanego przez obiekt Loader:

Do obiektu LoaderInfo można uzyskać dostęp jak do właściwości obiektu Loader i załadowanego obiektu wyświetlanego. Po rozpoczęciu ładowania do obiektu LoaderInfo można uzyskać za pośrednictwem właściwości contentLoaderInfo obiektu Loader. Po zakończeniu ładowania obiektu wyświetlanego do obiektu LoaderInfo można uzyskać dostęp w taki sposób, jak do właściwości obiektu załadowanego — za pośrednictwem właściwości loaderInfo obiektu wyświetlanego. Właściwość loaderInfo załadowanego obiektu wyświetlanego dotyczy tego samego obiektu LoaderInfo, co właściwość contentLoaderInfo obiektu Loader. Innymi słowy — obiekt Loaderinfo jest współużytkowany przez obiekt załadowany i obiekt Loader, który go załadował (współużytkowany przez obiekt ładowany i ładujący).

W celu uzyskania dostępu do ładowanej treści należy dodać do obiektu LoaderInfo detektor zdarzeń, jak w poniższym kodzie:

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; 
}

Więcej informacji zawiera sekcja Obsługa zdarzeń.

Określanie kontekstu ładowania

Podczas ładowania pliku zewnętrznego do programu Flash Player lub AIR za pośrednictwem metody load() lub metody loadBytes() klasy Loader możliwe jest określenie opcjonalnego parametru context. Ten parametr jest obiektem LoaderContext.

Klasa LoaderContext zawiera trzy właściwości, które umożliwiają zdefiniowanie kontekstu wykorzystania załadowanej treści:

  • checkPolicyFile: ta właściwość powinna być używana tylko w przypadku ładowania pliku obrazu (nie pliku SWF). Jeśli dla tej właściwości zostanie ustawiona wartość true, obiekt Loader sprawdzi serwer pochodzenia pliku strategii (patrz Internetowe elementy sterujące (pliki zasad)). Jest to konieczne tylko w przypadku treści pochodzącej z domen innych niż plik SWF zawierający obiekt Loader. Jeśli serwer uzyska dostęp do domeny Loader, wówczas kod ActionScript z plików SWF w domenie Loader będzie mógł uzyskać dostęp do danych z załadowanego obrazu; innymi słowy — możliwe będzie użycie polecenia BitmapData.draw() w celu uzyskania dostępu do danych w załadowanym obrazie.

    Należy zauważyć, że plik SWF z domen innych niż domena obiektu Loader może wywołać metodę Security.allowDomain(), aby zezwolić na wykorzystanie konkretnej domeny.

  • securityDomain: z tej właściwości można korzystać tylko podczas ładowania pliku SWF (nie obrazu). Metodę należy określić dla pliku SWF z domeny innej niż domena pliku zawierającego obiekt Loader. Po ustawieniu tej opcji program Flash Player sprawdza istnienie pliku strategii, a jeśli taki plik istnieje, wówczas pliki SWF z domen dozwolonych w pliku strategii międzydomenowej mogą wywoływać skrypty w ładowanej treści SWF. Jako parametr można ustawić flash.system.SecurityDomain.currentDomain.

  • applicationDomain: ta właściwość powinna być używana wyłącznie podczas ładowania pliku SWF zapisanego w języku ActionScript 3.0 (a nie obrazu lub pliku SWF zapisanego w języku ActionScript 1.0 lub 2.0). Podczas ładowania pliku można określić, że plik zostanie dołączony do tej samej domeny aplikacji, co obiekt Loader — w tym celu należy ustawić dla parametru applicationDomain wartość flash.system.ApplicationDomain.currentDomain. Umieszczenie załadowanego pliku SWF w tej samej domenie aplikacji umożliwia bezpośredni dostęp do jego klas. Można to wykorzystać podczas ładowania pliku SWF, który zawiera osadzone materiały multimedialne, do których dostęp można uzyskać za pośrednictwem nazw skojarzonych z nimi klas. Więcej informacji zawiera sekcja Praca z domenami aplikacji.

Poniżej przedstawiono przykład sprawdzania dostępności pliku strategii podczas ładowania bitmapy z innej domeny:

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);

Poniżej przedstawiono przykład sprawdzania dostępności pliku strategii podczas ładowania pliku SWF z innej domeny w celu umieszczenia pliku w tym samym bezpiecznym obszarze izolowanym, w którym znajduje się obiekt Loader. Ponadto kod dodaje klasy z załadowanego pliku SWF do tej samej domeny aplikacji, co obiekt Loader:

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);

Więcej informacji zawiera opis klasy LoaderContext w Skorowidzu języka ActionScript 3.0 dla platformy Adobe Flash.

Wczytywanie plików SWF w środowisku AIR for iOS

Na urządzeniach z systemem iOS występują ograniczenia dotyczące wczytywania i kompilowania kodu w czasie wykonywania. Te ograniczenia wymuszają nieco zmieniony sposób wczytywania zewnętrznych plików SWF do aplikacji:

  • Wszystkie pliki SWF zawierające kod ActionScript należy dołączyć do pakietu aplikacji. Żadnego pliku SWF zawierającego kod nie można wczytać ze źródła zewnętrznego, na przykład przez sieć. Podczas pakowania aplikacji cały kod ActionScript ze wszystkich plików SWF w pakiecie aplikacji jest kompilowany do kodu natywnego dla urządzeń z systemem iOS.

  • Nie można wczytać, usunąć i ponownie wczytać pliku SWF. Próba wykonania takiej operacji powoduje błąd.

  • Wczytywanie do pamięci i usuwanie z pamięci działa tak samo jak na platformach komputerowych. Gdy plik SWF zostanie usunięty po wczytaniu, wszystkie zasoby wirtualne zawarte w tym pliku zostaną usunięte z pamięci. W pamięci pozostaną jednak odniesienia do klas ActionScript z wczytanego pliku SWF i będzie można uzyskać do nich dostęp z poziomu kodu ActionScript.

  • Wszystkie pliki SWF należy wczytać do tej samej domeny aplikacji, do której należy główny plik SWF. To nie jest zachowanie domyślne, dlatego dla każdego pliku SWF należy utworzyć obiekt LoaderContext określający główną domenę aplikacji, a następnie przekazać ten obiekt do wywołania metody Loader.load(). Próba wczytania pliku SWF do domeny aplikacji innej niż domena aplikacji głównego pliku SWF powoduje błąd. Dzieje się tak nawet w przypadku, gdy wczytany plik SWF zawiera tylko zasoby wizualne — bez kodu ActionScript.

    Poniższy przykładowy kod ilustruje wczytywanie pliku SWF z pakietu aplikacji do domeny aplikacji głównego pliku SWF.

    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);

Plik SWF zawierający tylko zasoby (bez kodu) można wczytać z pakietu aplikacji lub przez sieć. W obu przypadkach konieczne jest wczytanie pliku SWF do głównej domeny aplikacji.

W wersji środowiska AIR starszej niż 3.6 w procesie kompilacji z plików SWF jest usuwany cały kod oprócz kodu głównego pliku SWF aplikacji. Pliki SWF zawierające tylko zasoby wizualne (bez kodu) można dołączyć do aplikacji i wczytać w czasie wykonywania. Próba wczytania pliku SWF zawierającego kod ActionScript powoduje błąd. W związku z takim błędem w aplikacji jest wyświetlane okno dialogowe „Nieskompilowany kod ActionScript”.

Zobacz także

Pakowanie i wczytywanie wielu plików SWF w aplikacjach AIR dla systemu iOS

Używanie klas ProLoader i ProLoaderInfo

W celu ułatwienia wstępnego wczytywania współużytkowanych bibliotek czasu wykonywania (RSL, Runtime Shared Library) w programie Flash Professional CS5.5 wprowadzono klasy fl.display.ProLoader i fl.display.ProLoaderInfo. Odpowiadają one klasom flash.display.Loader i flash.display.LoaderInfo, przy czym oferują spójniejszą obsługę wczytywania.

Klasa ProLoader ułatwia wczytywanie plików SWF, które korzystają z architektury Text Layout Framework (TLF) i wstępnego wczytywania RSL. W czasie wykonywania pliki SWF, które wczytują inne pliki SWF lub pliki SWZ, na przykład korzystające z architektury TLF, wymagają pliku opakowującego zawartość SWF wyłącznie do użytku wewnętrznego. Dodatkowa warstwa złożoności nałożona przez plik opakowujący SWF może spowodować niepożądane zachowanie. Klasa ProLoader radzi sobie z tą złożonością, wczytując te pliki tak, jakby były zwykłymi plikami SWF. Rozwiązanie zastosowane w klasie ProLoader jest przezroczyste dla użytkownika i nie wymaga wykonywania specjalnych czynności w kodzie ActionScript. Dodatkowo klasa ProLoader poprawnie wczytuje zwykłą zawartość SWF.

W programie Flash Professional w wersji CS5.5 lub nowszej można bezpiecznie zastąpić wszystkie wystąpienia klasy Loader wystąpieniami klasy ProLoader. Następnie należy wyeksportować aplikację do programu Flash Player 10.2 lub nowszego, tak aby obiekt ProLoader mógł uzyskać dostęp do odpowiedniej funkcji języka ActionScript. Można tez używać klasy ProLoader z myślą o wcześniejszych wersjach programu Flash Player, które obsługują język ActionScript 3.0, jednak pełne wykorzystanie funkcji tej klasy możliwe jest tylko w programie Flash Player 10.2 lub nowszym. Z klasy ProLoader należy korzystać zawsze w przypadku stosowania architektury TLF w programie Flash Professional CS5.5 lub nowszym. Klasa ProLoader nie jest potrzebna w środowiskach innych niż Flash Professional.

Ważne: Dla plików SWF opublikowanych w programie Flash Professional CS5.5 lub nowszym można zawsze używać klas fl.display.ProLoader i fl.display.ProLoaderInfo zamiast flash.display.Loader i flash.display.LoaderInfo.

Problemy rozwiązywane przez klasę ProLoader

Klasa ProLoader rozwiązuje problemy, których nie uwzględniono w projekcie starszej klasy Loader. Problemy te dotyczą wstępnego wczytywania współużytkowanych bibliotek czasu wykonywania architektury TLF. W szczególności dotyczą one plików SWF, które za pomocą obiektu Loader wczytują inne pliki SWF. Do rozwiązanych problemów należą:

  • Nieoczekiwane zachowania w skryptach działających pomiędzy plikiem wczytującym a wczytywanym. Klasa ProLoader automatycznie ustawia wczytujący plik SWF jako element macierzysty wczytanego pliku SWF. W takim przypadku komunikaty z wczytującego pliku SWF trafiają bezpośrednio do wczytanego pliku SWF.

  • Aplikacja SWF musi aktywnie kierować procesem wczytywania. To wymaga implementacji dodatkowych zdarzeń, takich jak added, removed, addedToStage i removedFromStage. Jeśli aplikacja jest przeznaczona do działania z programem Flash Player 10.2 lub nowszym, użycie klasy ProLoader pozwala uniknąć tej dodatkowej pracy.

Aktualizacja kodu w celu użycia klasy ProLoader zamiast Loader

Klasa ProLoader działa analogicznie do klasy Loader, dzięki czemu można w prosty sposób zamieniać te klasy w kodzie. Poniższy przykład ilustruje sposób aktualizacji istniejącego kodu w celu użycia nowej klasy.

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!'); 
}

Kod można w następujący sposób dostosować do używania klasy ProLoader.

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!'); 
}