Anropa och avsluta AIR-program

Adobe AIR 1.0 och senare

I det här avsnittet behandlas hur ett installerat Adobe® AIR®-program kan anropas liksom alternativ och överväganden vid avslutande av ett program som körs.

Obs! Objekten NativeApplication, InvokeEvent och BrowserInvokeEvent är bara tillgängliga för SWF-innehåll som körs i AIR-programmets sandlåda. SWF-innehåll som körs i Flash Player, antingen i webbläsaren eller i den fristående spelaren (projektorn), eller i ett AIR-program utanför programmets sandlåda, kan inte komma åt de här klasserna.

Följande snabbstartartiklar på Adobe Developer Connection innehåller information med korta förklaringar och kodexempel på hur du anropar och avslutar AIR-program:

Anropa program

Ett AIR-program anropas när användaren (eller operativsystemet):

  • Startar programmet från skrivbordsskalet.

  • Använder programmet som ett kommando i ett kommandoradsskal.

  • Öppnar en typ av fil som programmet är standardprogram för.

  • (Mac OS X) Klickar på programikonen i aktivitetsfältet (oavsett om programmet körs eller inte).

  • Väljer att starta programmet från installationsprogrammet (antingen i slutet av en ny installationsprocess eller efter att ha dubbelklickat på AIR-filen för ett redan installerat program).

  • Börjar en uppdatering av ett AIR-program när den installerade versionen har signalerat att den hanterar programuppdateringar själv (genom att ta med en <customUpdateUI>true</customUpdateUI> -deklaration i programbeskrivningsfilen).

  • (iOS) Erhåller ett meddelande från APN-tjänster (Apple Push Notification).

  • Aktiverar programmet via en URL-adress.

  • Besöker en webbsida som är värd för ett Flash-emblem eller ett program som anropar metoden com.adobe.air.AIR launchApplication() som anger ID-information för AIR-programmet. (Programbeskrivningen måste också omfatta en <allowBrowserInvocation>true</allowBrowserInvocation> -deklaration om webbläsaranrop ska lyckas.)

När ett AIR-program anropas skickas ett InvokeEvent-objekt av typen invoke via singleton-objektet NativeApplication. För att en programtid ska kunna initiera sig själv och registrera en händelseavlyssnare måste invoke -händelser ställas i kö i stället för att tas bort. Så snart en avlyssnare är registrerad levereras alla händelser som står i kö.

Obs! När ett program anropas med hjälp av webbläsarens anropsfunktion skickar objektet NativeApplication bara en invoke -händelse om programmet inte redan körs.

Om du vill ta emot invoke -händelser måste du anropa NativeApplication-objektets addEventListener() -metod ( NativeApplication.nativeApplication) . När en händelseavlyssnare registrerar sig till en invoke -händelse, kommer den också att få alla invoke -händelser som har inträffat före registreringen. invoke -händelser som står i kö skickas en i taget med korta intervall efter att anropet till addEventListener() returnerats. Om en ny invoke -händelse inträffar under den här processen kan den skickas före en eller flera av händelserna som står i kö. Tack vare det här kösystemet kan du hantera invoke -händelser som inträffar innan initieringskoden körs. Kom ihåg, att om du lägger till en händelseavlyssnare senare i körningen (efter programinitieringen) kommer den fortfarande att få alla invoke -händelser som har inträffat sedan programmet startade.

Bara en instans av ett AIR-program startar. När ett program som redan körs anropas igen, skickas en ny invoke -händelse till den instans som körs. Det åligger ett AIR-program att svara på en invoke -händelse och vidta rätt åtgärd (till exempel att öppna ett nytt dokumentfönster).

Ett InvokeEvent -objekt innehåller alla argument som skickas till programmet samt katalogen som programmet anropas från. Om programmet anropades med anledning av av en filtypsassociation, ingår den fullständiga sökvägen till filen i kommandoradsargumenten. Om programmet anropades med anledning av en programuppdatering anges också den fullständiga sökvägen till uppdateringsfilen.

Om flera filer öppnas i en åtgärd skickas ett enskilt InvokeEvent-objekt på Mac OS X. Varje fil inkluderas i argument -arrayen. På Windows och Linux skickas ett separat InvokeEvent-objekt för varje fil.

Programmet kan hantera invoke -händelser genom att registrera en avlyssnare med NativeApplication-objektet:

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

Och definiera en händelseavlyssnare:

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

Hämta kommandoradsargument

Kommandoradsargumenten som hör till ett AIR-programanrop levereras i InvokeEvent-objektet, som skickas av objektet NativeApplication. Egenskapen arguments för InvokeEvent innehåller en array med de argument som skickas av operativsystemet när ett AIR-program anropas. Om argumenten innehåller relativa filsökvägar kan du vanligtvis lösa sökvägen med hjälp av egenskapen currentDirectory .

De argument som skickas till ett AIR-program behandlas som blankstegsavgränsade strängar, såvida de inte omsluts av citattecken:

Argument

Array

tick tock

{tick,tock}

tick ”tick tock”

{tick,tick tock}

”tick” ”tock”

{tick,tock}

\”tick\” \”tock\”

{”tick”,”tock”}

Egenskapen currentDirectory för ett InvokeEvent-objekt innehåller ett File-objekt, som representerar den katalog programmet startas från.

När ett program anropas med anledning av att en fil av en typ som är registrerad av programmet öppnas, ingår den ursprungliga sökvägen till filen i kommandoradsargumenten som en sträng. (Programmet ansvarar för att öppna eller utföra den tänkta filåtgärden.) När ett program är programmerat att uppdatera sig självt (i stället för att använda det vanliga uppdateringsgränssnittet för AIR), inkluderas den ursprungliga sökvägen till AIR-filen när en användare dubbelklickar på en AIR-fil som finns i ett program med motsvarande program-ID.

Du får tillgång till filen med metoden resolve() för File-objektet currentDirectory :

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

Du bör också kontrollera att ett argument verkligen är sökvägen till en fil.

Exempel: Anropa händelseloggen

I följande exempel visas hur du registrerar händelseavlyssnare för och hanterar händelsen invoke . Exemplet loggar alla anropshändelser som tas emot och visar den aktuella katalogen och kommandoradsargumenten.

ActionScript-exempel

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

Flex-exempel

<?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>

Anropa ett AIR-program när användaren loggar in

Du kan ange att ett AIR-program ska startas automatiskt när den aktuella användaren logga in genom att ange egenskapen startAtLogin för NativeApplication till true . När du har gjort det startar programmet automatiskt när användaren loggar in. Det fortsättar att starta vid inloggning tills inställningen ändras till false , tills användaren ändrar inställningen manuellt via operativsystemet eller tills programmet avinstalleras. Att starta vid inloggning är en körningsinställning. Inställningen gäller bara för den aktuella användaren. Programmet måste vara installerat för att du ska kunna ställa in egenskapen startAtLogin true . Ett fel returneras om egenskapen ställs in när ett program inte är installerat (till exempel när det startas med ADL).

Obs! Programmet startas inte när datorsystemet startas. Det startas när användaren loggar in.

Om du vill veta om ett program har startats automatiskt eller om användaren har startat det kan du titta på egenskapen reason för InvokeEvent-objektet. Om egenskapen är lika med InvokeEventReason.LOGIN har programmet startats automatiskt. För andra anropssökvägar ställs egenskapen reason in enligt följande:

  • InvokeEventReason.NOTIFICATION (endast iOS) – Programmet anropades via APN:er. Mer information om APN:er finns i Använda push-meddelanden .

  • InvokeEventReason.OPEN_URL – Programmet anropades från annat program eller system.

  • InvokeEventReason.Standard – Alla andra fall.

För att komma åt egenskapen reason måste AIR 1.5.1 eller senare vara mål för ditt program (genom att du anger korrekt namnutrymmesvärde i programbeskrivningsfilen).

Följande förenklade program använder egenskapen reason för InvokeEvent för att fastställa hur det ska bete sig när en invoke-händelse inträffar. Om egenskapen reason är "login" ligger programmet kvar i bakgrunden. I annat fall visas huvudprogrammet för användaren. Ett program som använder det här mönstret startas vanligen vid inloggning så att det kan köra bakgrundsprocesser eller händelseövervakning, och ett fönster öppnas som svar på en invoke-händelse från användaren.

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(); 
            } 
        } 
    } 
}
Obs! Om du vill se skillnaden i beteende paketerar och installerar du programmet. Det går bara att ange egenskapen startAtLogin för installerade program.

Anropa ett AIR-program från webbläsaren

Med hjälp av webbläsarens anropsfunktion kan en webbplats starta ett installerat AIR-program från webbläsaren. Webbläsaranrop tillåts bara om programbeskrivningsfilen ställer in allowBrowserInvocation true :

<allowBrowserInvocation>true</allowBrowserInvocation>

När programmet anropas via webbläsaren skickar programmets NativeApplication-objekt ett BrowserInvokeEvent-objekt.

Om du vill ta emot BrowserInvokeEvent-händelser, måste du anropa metoden addEventListener() för NativeApplication-objektet ( NativeApplication.nativeApplication ) i AIR-programmet. När en händelseavlyssnare registrerar sig för en BrowserInvokeEvent-händelse, kommer den också att ta emot alla BrowserInvokeEvent-händelser som har inträffat före registreringen. Dessa händelser skickas efter att anropet addEventListener() returneras, men inte nödvändigtvis före andra BrowserInvokeEvent-händelser som tas emot efter registreringen. Detta innebär att du kan hantera BrowserInvokeEvent-händelser som har inträffat innan din initieringskod verkställs (som när programmet anropas från webbläsaren). Kom ihåg, att om du lägger till en händelseavlyssnare senare i körningen (efter programinitieringen) kommer den fortfarande att få alla BrowserInvokeEvent-händelser som har inträffat sedan programmet startade.

BrowserInvokeEvent-objektet har följande egenskaper:

Egenskap

Beskrivning

argument

En array med argument (strängar) som ska skickas till programmet.

isHTTPS

Anger om innehållet i webbläsaren använder https-URL-schemat ( true ) eller inte ( false ).

isUserEvent

Anger om webbläsaranropet resulterar i en användarhändelse (t.ex. ett musklick). I AIR 1.0 är detta alltid inställt på true . AIR kräver en användarhändelse för webbläsaranropsfunktionen.

sandboxType

Sandlådetypen för innehållet i webbläsaren. Giltiga värden är samma som dem som kan användas i egenskapen Security.sandboxType , och kan vara något av följande:

  • Security.APPLICATION – Innehållet finns i programmets säkerhetssandlåda.

  • Security.LOCAL_TRUSTED – Innehållet finns i lokal-med-filsystems säkerhetssandlåda.

  • Security.LOCAL_WITH_FILE – Innehållet finns i lokal-med-filsystems säkerhetssandlåda.

  • Security.LOCAL_WITH_NETWORK – Innehållet finns i lokal-med-nätverkstjänsts säkerhetssandlåda.

  • Security.REMOTE – Innehållet är i en fjärrdomän (nätverk).

securityDomain

Säkerhetsdomänen för innehållet i webbläsaren som t.ex. "www.adobe.com" eller "www.example.org" . Den här egenskapen ställs bara in för innehåll i fjärrsäkerhetssandlådan (för innehåll från en nätverksdomän). Den ställs inte in för innehåll i en lokal sandlåda eller en av typen application.

Om du använder funktionen för webbläsaranrop måste du tänka på säkerheten. När en webbplats startar ett AIR-program kan den skicka data via egenskapen arguments för objektet BrowserInvokeEvent. Var försiktig när du använder dessa data i känsliga åtgärder, till exempel API:er för fil- eller kodinläsning. Risknivån beror på vad programmet gör med informationen. Om du förväntar dig att bara en viss webbplats ska anropa programmet bör programmet kontrollera egenskapen securityDomain för objektet BrowserInvokeEvent. Du kan också kräva att den webbplats som anropar programmet använder HTTPS, vilket du kan verifiera genom att kontrollera egenskapen isHTTPS för objektet BrowserInvokeEvent.

Programmet bör verifiera de data som skickas. Om till exempel ett program förväntas att skicka URL:er till en viss domän, bör det verifiera att dessa URL:er verkligen pekar på den domänen. Detta förhindrar att en angripare kan lura programmet att skicka känsliga data.

Inget program bör använda BrowserInvokeEvent-argument som pekar på lokala resurser. Ett program bör till exempel inte skapa File-objekt som baseras på en sökväg som skickas från webbläsaren. Om fjärrsökvägen förväntas bli skickad från webbläsaren, bör programmet se till att sökvägarna inte använder protokollet file:// i stället för ett fjärrprotokoll.

Avsluta program

Det snabbaste sättet att avsluta ett program är att anropa metoden NativeApplication exit(). Det fungerar utmärkt när programmet inte behöver spara data eller rensa externa resurser. När du anropar exit() stängs alla fönster och sedan avslutas programmet. Om du vill tillåta att fönster eller andra komponenter i programmet avbryter avslutningsprocessen, kanske för att spara viktiga data, ska du skicka rätt varningshändelser innan exit() anropas.

Något annat som du behöver tänka på när det gäller att stänga ett program är att tillhandahålla en enda körningssökväg, oavsett hur avstängningsprocessen startar. Användaren (eller operativsystemet) kan utlösa programavslut på följande sätt:

  • Genom att stänga det sista programfönstret när NativeApplication.nativeApplication.autoExit är true .

  • Genom att välja programavslutskommandot från operativsystemet, till exempel när användaren väljer programavslutskommandot på standardmenyn. (Detta händer bara i Mac OS. I Windows och Linux går det inte att avsluta programmet via systemets fönsterstandard.)

  • Genom att stänga av datorn.

När ett avslutskommando skickas via operativsystemet utmed någon av dessa vägar, skickar NativeApplication en exiting -händelse. Om ingen avlyssnare avbryter exiting -händelsen stängs alla öppna fönster. Varje fönster skickar en closing -händelse och sedan en close -händelse. Om något av fönstren avbryter closing -händelsen stannar avstängningsprocessen.

Om den ordning som fönstren stängs i är viktig för programmet, lyssnar du efter exiting -händelsen från NativeApplication och stänger fönstren själv i rätt ordning. Du kan till exempel behöva göra det om du har ett dokumentfönster med verktygspaletter. Det kan vara opraktiskt eller ännu värre om systemet stänger paletterna, men användaren bestämmer sig för att avbryta avslutskommandot för att spara data. Den enda gången som du får en exiting -händelse i Windows är efter att du har stängt det sista fönstret (när egenskapen autoExit för NativeApplication-objektet ställs in på true ).

Om du vill att beteendet ska vara detsamma på alla plattformar, oavsett om avslutssekvensen sätts igång via operativsystemet, menykommandon eller programlogik, bör du utgå från följande metodtips för att avsluta programmet:

  1. Skicka alltid en exiting -händelse via objektet NativeApplication innan du anropar exit() i programkoden och kontrollera att ingen annan komponent i programmet avbryter händelsen.

    public function applicationExit():void { 
        var exitingEvent:Event = new Event(Event.EXITING, false, true); 
        NativeApplication.nativeApplication.dispatchEvent(exitingEvent); 
        if (!exitingEvent.isDefaultPrevented()) { 
            NativeApplication.nativeApplication.exit(); 
        } 
    } 
  2. Lyssna efter programmets exiting -händelse från objektet NativeApplication.nativeApplication och stäng alla fönster i hanteraren (skicka först en closing -händelse). Utför de rensningsuppgifter som behövs, till exempel spara programdata eller ta bort tillfälliga filer, när alla fönster har stängts. Använd bara synkrona metoder under rensningen så att du är säker på att de är klara innan programmet avslutas.

    Om det inte spelar någon roll i vilken ordning fönstren stängs, kan du göra en slinga genom NativeApplication.nativeApplication.openedWindows -arrayen och stänga fönstren i tur och ordning. Om ordningen spelar roll tillhandahåller du ett sätt att stänga fönstren i rätt ordning.

    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. Fönster ska alltid hantera sin egen upprensning genom att avlyssna sina egna closing -händelser.

  4. Använd bara en exiting -avlyssnare i programmet eftersom hanterare som anropas tidigare inte kan veta om efterföljande hanterare kommer att avbryta exiting -händelsen (och det vore dumt att lita på körningsordningen).