Wywoływanie i kończenie działania aplikacji AIR

Adobe AIR 1.0 i starsze wersje

W tej sekcji omówiono dostępne sposoby wywoływania zainstalowanej aplikacji dla środowiska Adobe® AIR®, a także opcje i uwarunkowania związane z zamykaniem działającej aplikacji.

Uwaga: Obiekty NativeApplication, InvokeEvent i BrowserInvokeEvent są dostępne tylko dla treści SWF działającej w obszarze izolowanym aplikacji AIR. Treść SWF działająca w środowisku wykonawczym odtwarzacza Flash Player, w przeglądarce lub w odtwarzaczu autonomicznym (projektorze), lub w aplikacji AIR poza obszarem izolowanym aplikacji, nie ma dostępu do tych klas.

Skrócone omówienia i przykłady kodu ilustrujące wywoływanie i kończenie działania aplikacji AIR można znaleźć w następujących artykułach z serii Quick Start w witrynie Adobe Developer Connection:

Wywoływanie aplikacji

Aplikacja AIR zostaje wywołana, gdy użytkownik (lub system operacyjny):

  • Uruchomi aplikację z pulpitu.

  • Użyje aplikacji jako polecenia z poziomu wiersza poleceń.

  • Otworzy typ pliku, dla którego aplikacja stanowi domyślną aplikację podczas otwierania.

  • (W systemie Mac OS X) kliknie ikonę aplikacji na pasku zadań (bez względu, czy aplikacja jest aktualnie uruchomiona).

  • Uruchomi aplikację za pomocą instalatora (na zakończenie procesu nowej instalacji lub po dwukrotnym kliknięciu pliku AIR już zainstalowanej aplikacji).

  • Rozpocznie aktualizację aplikacji AIR, gdy zainstalowana wersja poinformuje o automatycznym przeprowadzaniu aktualizacji (przez uwzględnienie deklaracji <customUpdateUI>true</customUpdateUI> w pliku deskryptora aplikacji).

  • (W systemie iOS) Otrzyma powiadomienie z usługi Apple Push Notification (APN).

  • Wywoła aplikację, korzystając z adresu URL.

  • Przejdzie na stronę internetową z identyfikatorem Flash lub do aplikacji wywołującej metodę com.adobe.air.AIR launchApplication() określającą informacje identyfikacyjne dla aplikacji AIR. (Deskryptor aplikacji musi także zawierać deklarację <allowBrowserInvocation>true</allowBrowserInvocation> , aby wywołanie zakończyło się powodzeniem).

Każdorazowo po wywołaniu aplikacji AIR, aplikacja ta wywołuje obiekt InvokeEvent typu invoke za pomocą obiektu singletonowego NativeApplication. Aby aplikacja miała czas na zainicjowanie i zarejestrowanie detektora zdarzeń, zdarzenia invoke są dodawane do kolejki, a nie pomijane. Po zarejestrowaniu detektora dostarczane są wszystkie zdarzenia z kolejki.

Uwaga: Po wywołaniu aplikacji za pomocą funkcji wywołania w przeglądarce, obiekt NativeApplication wywołuje zdarzenie invoke jedynie w przypadku, gdy aplikacja nie została jeszcze uruchomiona.

Aby odebrać zdarzenia invoke , należy wywołać metodę addEventListener() obiektu NativeApplication ( NativeApplication.nativeApplication) . Po zarejestrowaniu detektora dla zdarzenia invoke odebrane są również wszystkie zdarzenia invoke mające miejsce przed rejestracją. Zdarzenia invoke z kolejki są wywoływane pojedynczo w krótkich odstępach czasu po zwróceniu wywołania addEventListener() . Jeśli nowe zdarzenie invoke pojawi się w tym procesie, może zostać wywołane przed jednym lub większą liczbą zdarzeń z kolejki. Kolejka zdarzeń umożliwia obsługę dowolnych zdarzeń invoke mających miejsce przed wykonaniem kodu inicjowania. Należy pamiętać, że po późniejszym dodaniu detektora zdarzeń w czasie wykonywania (po inicjalizacji aplikacji), dalej będą odbierane wszystkie zdarzenia invoke mające miejsce od czasu uruchomienia aplikacji.

Zostaje uruchomiona wyłącznie jedna instancja aplikacji AIR. Gdy już uruchomiona aplikacja jest wywołana ponownie, AIR wywołuje nowe zdarzenie invoke dla działającej instancji. Do zadań aplikacji AIR należy odpowiadane na zdarzenie invoke i wykonanie odpowiedniej czynności (np. otwarcie nowego okna dokumentu).

Obiekt InvokeEvent zawiera wszystkie argumenty przekazane do aplikacji oraz katalog, z którego aplikacja została wywołana. Jeśli aplikacja została wywołana poprzez powiązanie z typem pliku, pełna ścieżka do pliku jest zawarta w argumentach wiersza poleceń. Podobnie, jeśli aplikacja została wywołana poprzez aktualizację aplikacji, zawarta jest pełna ścieżka do zaktualizowanego pliku AIR.

Jeśli w pojedynczej operacji zostanie otwartych wiele plików, w systemie Mac OS X zostanie wywołany jeden obiekt InvokeEvent. Każdy z plików jest zawarty w tablicy arguments . W systemach Windows i Linux dla każdego pliku zostanie wywołany osobny obiekt InvokeEvent.

Aplikacja może obsługiwać zdarzenia invoke poprzez zarejestrowanie detektora z obiektem NativeApplication:

NativeApplication.nativeApplication.addEventListener(InvokeEvent.INVOKE, onInvokeEvent); 

Oraz poprzez zdefiniowanie detektora zdarzeń:

var arguments:Array; 
var currentDir:File; 
public function onInvokeEvent(invocation:InvokeEvent):void { 
    arguments = invocation.arguments; 
    currentDir = invocation.currentDirectory; 
} 

Przechwytywanie argumentów wiersza poleceń

Argumenty wiersza poleceń powiązane z wywołaniem aplikacji AIR są dostarczone w obiekcie InvokeEvent przez obiekt NativeApplication. Właściwość InvokeEvent arguments zawiera tablicę przekazaną przez system operacyjny podczas wywoływania aplikacji AIR. Jeśli argumenty zawierają względne ścieżki pliku, można zazwyczaj je rozwiązać poprzez użycie właściwości currentDirectory .

Argumenty przekazane do programu AIR są traktowane jako ciągi ograniczone spacjami, chyba że zostaną ujęte w podwójne cudzysłowy:

Argumenty

Array

tick tock

{tick,tock}

tick "tick tock"

{tick,tick tock}

"tick" “tock”

{tick,tock}

\"tick\" \"tock\"

{"tick","tock"}

Właściwość currentDirectory obiektu InvokeEvent zawiera obiekt File reprezentujący katalog, z którego została uruchomiona aplikacja.

Gdy aplikacja zostaje wywołana, ponieważ otwarty został plik, którego typ jest zarejestrowany przez aplikację, własna ścieżka do pliku jest zawarta jako łańcuch w argumentach wiersza poleceń. (Aplikacja odpowiada za zaczynanie i wykonywanie zamierzonej czynności w pliku). Podobnie, po zaprogramowaniu aplikacji do automatycznej aktualizacji (a nie za pomocą standardowego interfejsu użytkownika aktualizacji AIR), natywna ścieżka pliku AIR zostaje uwzględniona po dwukrotnym kliknięciu pliku AIR zawierającego aplikację ze zgodnym identyfikatorem aplikacji.

Dostęp do pliku można uzyskać za pomocą metody resolve() obiektu File currentDirectory :

if((invokeEvent.currentDirectory != null)&&(invokeEvent.arguments.length > 0)){ 
    dir = invokeEvent.currentDirectory; 
    fileToOpen = dir.resolvePath(invokeEvent.arguments[0]); 
}

Należy również zatwierdzić argument jako ścieżkę pliku.

Przykład: dziennik zdarzeń wywołania

Następujący przykład przedstawia sposób rejestracji detektorów i obsługi zdarzeń invoke . W przykładzie zapisane zostają wszystkie zdarzenia wywołania i wyświetlony zostaje bieżący katalog oraz argumenty wiersza poleceń.

Przykład w języku ActionScript

package  
{ 
    import flash.display.Sprite; 
    import flash.events.InvokeEvent; 
    import flash.desktop.NativeApplication; 
    import flash.text.TextField; 
         
    public class InvokeEventLogExample extends Sprite 
    { 
        public var log:TextField; 
         
        public function InvokeEventLogExample() 
        { 
            log = new TextField(); 
            log.x = 15; 
            log.y = 15; 
            log.width = 520; 
            log.height = 370; 
            log.background = true; 
             
            addChild(log); 
 
            NativeApplication.nativeApplication.addEventListener(InvokeEvent.INVOKE, onInvoke); 
        } 
             
        public function onInvoke(invokeEvent:InvokeEvent):void 
        { 
            var now:String = new Date().toTimeString(); 
            logEvent("Invoke event received: " + now); 
                     
            if (invokeEvent.currentDirectory != null) 
            { 
                logEvent("Current directory=" + invokeEvent.currentDirectory.nativePath); 
            }  
            else  
            { 
                logEvent("--no directory information available--"); 
            } 
                     
            if (invokeEvent.arguments.length > 0) 
            { 
                logEvent("Arguments: " + invokeEvent.arguments.toString()); 
            }  
            else  
            { 
                logEvent("--no arguments--"); 
            } 
        } 
                 
        public function logEvent(entry:String):void  
        { 
            log.appendText(entry + "\n"); 
            trace(entry); 
        } 
    } 
} 

Przykład w środowisku Flex

<?xml version="1.0" encoding="utf-8"?> 
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" 
    invoke="onInvoke(event)" title="Invocation Event Log"> 
    <mx:Script> 
    <![CDATA[ 
    import flash.events.InvokeEvent; 
    import flash.desktop.NativeApplication; 
 
    public function onInvoke(invokeEvent:InvokeEvent):void { 
        var now:String = new Date().toTimeString(); 
        logEvent("Invoke event received: " + now); 
                 
        if (invokeEvent.currentDirectory != null){ 
            logEvent("Current directory=" + invokeEvent.currentDirectory.nativePath); 
        } else { 
            logEvent("--no directory information available--"); 
        } 
                 
        if (invokeEvent.arguments.length > 0){ 
            logEvent("Arguments: " + invokeEvent.arguments.toString()); 
        } else { 
            logEvent("--no arguments--"); 
        } 
    } 
             
    public function logEvent(entry:String):void { 
        log.text += entry + "\n"; 
        trace(entry); 
    } 
    ]]> 
    </mx:Script> 
    <mx:TextArea id="log" width="100%" height="100%" editable="false" 
        valueCommit="log.verticalScrollPosition=log.textHeight;"/> 
</mx:WindowedApplication>

Wywoływanie aplikacji AIR podczas logowania użytkownika

Aplikację AIR można ustawić, tak aby aplikacja była automatycznie uruchamiana podczas logowania użytkownika poprzez ustawienie właściwości startAtLogin obiektu NativeApplication na wartość true . Po ustawieniu aplikacja jest uruchamiana automatycznie za każdym razem podczas logowania użytkownika. Aplikacja jest uruchamiania w ten sposób do czasu zmiany ustawienia na wartość false . Ustawienia można zmieniać ręcznie poprzez system operacyjny lub aplikacja zostanie odinstalowana. Uruchamianie podczas logowania to ustawienie środowiska wykonawczego. To ustawienie ma zastosowanie wyłącznie do bieżącego użytkownika. Aplikacja musi być zainstalowana, aby dla właściwości startAtLogin można było ustawić wartość true . Jeśli właściwość zostanie ustawiona, gdy aplikacja nie będzie zainstalowana (na przykład podczas uruchamiania za pomocą modelu ADL), zostanie wygenerowany wyjątek.

Uwaga: Aplikacja nie jest uruchamiana w momencie uruchomienia systemu (komputera). Zostaje uruchomiona podczas logowania użytkownika.

Aby ustalić, czy aplikacja została uruchomiona automatycznie, czy w wyniku działania użytkownika, można odczytać właściwość reason obiektu InvokeEvent. Jeśli właściwość jest równa InvokeEventReason.LOGIN , aplikacja została uruchomiona automatycznie. W przypadku innych ścieżek wywołania właściwość reason jest ustawiana następująco:

  • InvokeEventReason.NOTIFICATION (tylko w systemie iOS) — aplikacja została wywołana za pomocą usługi APN. Więcej informacji o usłudze APN znajduje się w temacie Używanie powiadomień w trybie push .

  • InvokeEventReason.OPEN_URL — aplikacja została wywołana przez inną aplikację lub przez system.

  • InvokeEventReason.Standard — wszystkie pozostałe sytuacje.

Aby właściwość reason była dostępna, aplikacja musi być przeznaczona dla środowiska AIR 1.5.1 lub nowszego (w pliku deskryptora aplikacji musi być określona właściwa wartość przestrzeni nazw).

W poniższej uproszczonej aplikacji użyto właściwości reason obiektu InvokeEvent w celu wyboru zachowania po wystąpieniu zdarzenia invoke. Jeśli właściwość reason jest równa "login", aplikacja pozostaje w tle. W przeciwnym razie główne okno aplikacji staje się widoczne. Aplikacje korzystające z tego schematu zwykle uruchamiane są przy logowaniu i mogą realizować przetwarzanie w tle lub monitorować zdarzenia. Okno aplikacji jest otwierane w wyniku wywołania przez użytkownika zdarzenia invoke.

package { 
    import flash.desktop.InvokeEventReason; 
    import flash.desktop.NativeApplication; 
    import flash.display.Sprite; 
    import flash.events.InvokeEvent; 
 
    public class StartAtLogin extends Sprite 
    { 
        public function StartAtLogin() 
        { 
            try 
            { 
                NativeApplication.nativeApplication.startAtLogin = true; 
            } 
            catch ( e:Error ) 
            { 
                trace( "Cannot set startAtLogin:" + e.message ); 
            } 
             
            NativeApplication.nativeApplication.addEventListener( InvokeEvent.INVOKE, onInvoke ); 
        } 
                 
        private function onInvoke( event:InvokeEvent ):void 
        { 
            if( event.reason == InvokeEventReason.LOGIN ) 
            { 
                //do background processing... 
                trace( "Running in background..." ); 
            }             
            else 
            { 
                this.stage.nativeWindow.activate(); 
            } 
        } 
    } 
}
Uwaga: Aby porównać zachowania, należy spakować i zainstalować aplikację. Właściwość startAtLogin może być ustawiona tylko dla aplikacji zainstalowanych.

Wywoływanie aplikacji AIR z przeglądarki

Za pomocą funkcji wywoływania z przeglądarki strona internetowa może uruchomić z przeglądarki zainstalowaną aplikację AIR. Wywołanie z przeglądarki jest dozwolone wyłącznie wtedy, gdy w pliku deskryptora aplikacji dla właściwości allowBrowserInvocation jest ustawiona wartość true .

<allowBrowserInvocation>true</allowBrowserInvocation>

Gdy aplikacja jest wywołana za pomocą przeglądarki, obiekt aplikacji NativeApplication wywołuje obiekt BrowserInvokeEvent.

Aby odebrać zdarzenia BrowserInvokeEvent, należy wywołać metodę addEventListener() obiektu NativeApplication ( NativeApplication.nativeApplication ) w aplikacji AIR. Po zarejestrowaniu detektora dla zdarzenia BrowserInvokeEvent odebrane są również wszystkie zdarzenia BrowserInvokeEvent mające miejsce przed rejestracją. Te zdarzenia są wywołanie po zwróceniu wywołania addEventListener() , ale niekoniecznie przed innymi zdarzeniami BrowserInvokeEvent, które mogą być odebrane po rejestracji. Umożliwia to obsługę zdarzeń BrowserInvokeEvent, które mają miejsce przed wykonaniem kodu inicjalizacji (np. kiedy aplikacja została początkowo wywołana z przeglądarki). Należy pamiętać, że po późniejszym dodaniu detektora zdarzeń w czasie wykonywania (po inicjalizacji aplikacji), dalej będą odbierane wszystkie zdarzenia BrowserInvokeEvent mające miejsce od czasu uruchomienia aplikacji.

W obiekcie BrowserInvokeEvent znajdują się następujące właściwości:

Właściwość

Opis

arguments

Tablica argumentów (ciągów) przekazywanych do aplikacji.

isHTTPS

Określa, czy treść w przeglądarce korzysta ze schematu https URL ( true ) bądź z niego nie korzysta ( false ).

isUserEvent

Określa, czy wywołanie z przeglądarki spowodowało zdarzenie użytkownika (np. kliknięcie myszy). W przypadku wersji AIR 1.0 dla tej właściwości ustawiona jest zawsze wartość true ; w aplikacji AIR dla funkcji wywołania z przeglądarki wymagane jest zdarzenie użytkownika.

sandboxType

Typ obszaru izolowanego dla treści w przeglądarce. Zdefiniowane poprawne wartości są takie same, co wartości użyte we właściwości Security.sandboxType i mogą to być:

  • Security.APPLICATION — Treść znajduje się w obszarze izolowanym aplikacji.

  • Security.LOCAL_TRUSTED — Treść znajduje się w lokalnym obszarze izolowanym z systemem plików.

  • Security.LOCAL_WITH_FILE — Treść znajduje się w lokalnym obszarze izolowanym z systemem plików.

  • Security.LOCAL_WITH_NETWORK — Treść znajduje się w lokalnym obszarze izolowanym z obsługą sieci.

  • Security.REMOTE — Treść znajduje się zdalnej domenie (sieci).

securityDomain

Domena zabezpieczeń treści w przeglądarce, np. "www.adobe.com" lub "www.example.org" . Ta właściwość jest ustawiona wyłącznie dla treści w zdalnym obszarze zabezpieczeń (dla treści z domeny sieci). Nie jest ustawiona dla treści w lokalnym lub aplikacyjnym obszarze zabezpieczeń.

W przypadku używania funkcji wywoływania z przeglądarki należy uwzględnić kwestie zabezpieczeń. W przypadku uruchomienia aplikacji AIR ze strony internetowej, dane mogą być przesyłane za pomocą właściwości arguments obiektu BrowserInvokeEvent. Należy zachować ostrożność podczas korzystania z tych danych w operacjach wrażliwych np. interfejsy API ładowania pliku lub kodu. Poziom ryzyka zależy od sposobu wykorzystania danych przez aplikację. Jeśli wyłącznie określona strona sieci Web ma wywołać aplikację, aplikacja powinna sprawdzić wartość właściwości securityDomain obiektu BrowserInvokeEvent. Od strony sieci Web wywołującej aplikację można również wymagać użycia protokołów HTTP, które można określić poprzez sprawdzenie wartości isHTTPS obiektu BrowserInvokeEvent.

Aplikacja powinna zatwierdzić przekazywane dane. Na przykład, jeśli aplikacja oczekuje na przekazanie do niej adresów URL do określonej domeny, powinna zatwierdzić, że adresy URL naprawdę wskazują na tę domenę. Dzięki temu możliwe jest zapobiegnięcie wysłania wrażliwych danych pod niewłaściwe adresy.

Żadna aplikacja nie powinna korzystać z argumentów BrowserInvokeEvent, które mogą odwoływać się do lokalnych zasobów: Na przykład, aplikacja nie powinna tworzyć obiektów File w oparciu o ścieżkę przekazaną z przeglądarki. Jeśli oczekiwane jest przekazywanie ścieżek zdalnych z przeglądarki, aplikacja powinna sprawdzić, czy ścieżki nie używają protokołu file:// zamiast zdalnego protokołu.

Kończenie działania aplikacji

Najszybszym sposobem zakończenia działania aplikacji jest wywołanie metody exit() obiektu NativeApplication. Takie rozwiązanie jest wystarczające, jeśli w aplikacji nie ma danych do zapisania ani zasobów zewnętrznych, które należy zwolnić. Wywołanie metody exit() zamyka wszystkie okna, a następnie zamyka aplikację. Jednak, aby okna i inne komponenty mogły przerywać proces zamykania, np. w celu zapisania ważnych danych, należy wywołać odpowiednie zdarzenia ostrzegawcze przed wywołaniem metody exit() .

Kolejnym ułatwieniem podczas zamykania aplikacji jest podanie jednej ścieżki wykonania bez względu na sposób rozpoczęcia procesu zamykania. Użytkownik (lub system operacyjny) może wyzwolić zamknięcie aplikacji poprzez:

  • Zamknięcie ostatniego okna aplikacji, gdy właściwość NativeApplication.nativeApplication.autoExit na wartość true .

  • Wybranie polecenia zamknięcia systemu operacyjnego; na przykład gdy użytkownik wybierze polecenie zamknięcia aplikacji z menu domyślnego. (Taka sytuacja ma miejsce jedynie w systemach Mac OS. Systemy Windows i Linux nie udostępniają aplikacji polecenia zamknięcia za pośrednictwem karnacji systemu).

  • Wyłączenie komputera.

Kiedy polecenie zamknięcia jest przekazane poprzez system operacyjny na jeden z tych sposobów, obiekt NativeApplication wywołuje zdarzenie exiting . Jeśli żaden z detektorów nie anuluje zdarzenia exiting , wszystkie otwarte okna zostaną zamknięte. Każde okno wywołuje zdarzenie closing , a następnie close . Jeśli dowolne okno anuluje zdarzenie closing , proces zamykania zostaje przerwany.

Jeśli kolejność zamykania okien stanowi problem dla aplikacji, należy wywołać zdarzenie exiting z obiektu NativeApplication i samemu zamknąć okna w odpowiedniej kolejności. Bywa to celowe np. w sytuacji, gdy okno dokumentu zawiera palety. Taka sytuacja może być niekorzystna, jeśli system zamknie palety, a użytkownik będzie chciał anulować polecenie zamknięcia w celu zapisania danych. W systemie Windows zdarzenie exiting ma miejsce wyłącznie po zamknięciu ostatniego okna (kiedy właściwość autoExit obiektu NativeApplication ma wartość true ).

Aby zapewnić takie same ustawienia na wszystkich platformach, bez względu czy kolejność zamykania jest inicjowana za pośrednictwem karnacji systemu operacyjnego, polecenia menu lub logikę aplikacji, należy przestrzegać następujących zalecanych sposobów zamykania aplikacji:

  1. Zawsze należy wywołać zdarzenie exiting za pomocą obiektu NativeApplication przed wywołaniem metody exit() w kodzie aplikacji i sprawdzić, czy inny komponent aplikacji nie anuluje zdarzenia.

    public function applicationExit():void { 
        var exitingEvent:Event = new Event(Event.EXITING, false, true); 
        NativeApplication.nativeApplication.dispatchEvent(exitingEvent); 
        if (!exitingEvent.isDefaultPrevented()) { 
            NativeApplication.nativeApplication.exit(); 
        } 
    } 
  2. Wywołaj zdarzenie aplikacji exiting z obiektu NativeApplication.nativeApplication i w module obsługi zamknąć wszystkie okna (wywołując najpierw zdarzenie closing ). Wykonaj wszystkie niezbędne zadania czyszczenia, takie jak zapisanie danych aplikacji, usuwanie plików tymczasowych, po zamknięciu wszystkich okien. Podczas czyszczenia należy stosować wyłącznie synchroniczne metody, aby zapewnić, że zostaną zakończone przed zamknięciem aplikacji.

    Jeśli kolejność zamykania okien nie ma znaczenia, można wówczas przejść do tablicy NativeApplication.nativeApplication.openedWindows zamknąć kolejno każde okno. Jeśli kolejność ma znaczenie, należy skorzystać z metody zamykania okien w odpowiedniej kolejności.

    private function onExiting(exitingEvent:Event):void { 
        var winClosingEvent:Event; 
        for each (var win:NativeWindow in NativeApplication.nativeApplication.openedWindows) { 
            winClosingEvent = new Event(Event.CLOSING,false,true); 
            win.dispatchEvent(winClosingEvent); 
            if (!winClosingEvent.isDefaultPrevented()) { 
                win.close(); 
            } else { 
                exitingEvent.preventDefault(); 
            } 
        } 
         
        if (!exitingEvent.isDefaultPrevented()) { 
            //perform cleanup 
        } 
    } 
  3. Okna powinny zawsze obsługiwać własne zadania oczyszczania poprzez wywoływanie własnych zdarzeń closing .

  4. W aplikacji należy użyć wyłącznie jednego detektora zdarzeń exiting , ponieważ moduły obsługi wywołane wcześniej, nie wiedzą, czy kolejne moduły będą anulować zdarzenie exiting (nierozsądnie jest opierać się tylko na kolejności wykonywania).