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:
-
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();
}
}
-
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
}
}
-
Okna powinny zawsze obsługiwać własne zadania oczyszczania poprzez wywoływanie własnych zdarzeń
closing
.
-
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).
|
|
|