アプリケーションの起動および終了オプション



この節では、インストールした Adobe® AIR™ アプリケーションの起動、および実行中のアプリケーションの終了に使用するオプションと考慮事項について説明します。

アプリケーションの呼び出し

AIR アプリケーションは、ユーザ(またはオペレーティングシステム)が次の動作を行った場合に呼び出されます。

  • アプリケーションをデスクトップシェルから起動する。

  • アプリケーションをコマンドラインシェルのコマンドとして使用する。

  • アプリケーションがデフォルトで関連付けられている種類のファイルを開く。

  • (Mac OS X)ドックタスクバーでアプリケーションアイコンをクリックする(アプリケーションが現在実行中であるかどうかは問いません)。

  • インストーラでアプリケーションの起動を選択する(新規インストール作業の最後、またはインストール済みアプリケーションの AIR ファイルをダブルクリックした後)。

  • インストールされたバージョンがアプリケーションのアップデートを自動処理していることを表示したときに、AIR アプリケーションのアップデートを開始する(アプリケーション記述ファイルに <customUpdateUI>true</customUpdateUI> 宣言を含めている場合)。

  • AIR アプリケーション向けの識別情報を指定した com.adobe.air.AIR launchApplication() メソッドを呼び出す Flash バッジまたはアプリケーションをホストしている Web ページを表示する(ブラウザによる呼び出しを可能にするには、アプリケーション記述子に <allowBrowserInvocation>true</allowBrowserInvocation> 宣言も含まれている必要があります)。ブラウザからインストールされた AIR アプリケーションの起動を参照してください。

AIR アプリケーションが呼び出されるたびに、AIR はシングルトンの NativeApplication オブジェクトを通じて、型 invoke の InvokeEvent オブジェクトを送出します。アプリケーション時間が自分自身を初期化し、イベントリスナーを登録できるようにするには、invoke イベントを破棄せず、キューに入れる必要があります。リスナーが登録されると、キューに入れられているすべてのイベントが直ちに送出されます。

注意: ブラウザ呼び出し機能を使用してアプリケーションが呼び出されると、NativeApplication オブジェクトは、そのアプリケーションが既に実行中でなければ、invoke イベントのみを送出します。ブラウザからインストールされた AIR アプリケーションの起動を参照してください。

invoke イベントを受け取るには、NativeApplication オブジェクト(NativeApplication.nativeApplication)の addEventListener() メソッドを呼び出します。イベントリスナーは、invoke イベントについて登録されると、登録前に発生したすべての invoke イベントも受け取ります。キューに入れられた invoke イベントは、addEventListener() に対する呼び出しが返された後、短い間隔で一度に 1 つずつ送出されます。このプロセス中に新しい invoke イベントが発生した場合、このイベントを、キューに入れられた 1 つ以上のイベントが送出される前に送出することができます。このイベントキューイングにより、初期化コードが実行される前に発生した任意の invoke イベントを処理できます。イベントリスナーは、実行の比較的遅い時点(アプリケーション初期化の後)で追加された場合でも、アプリケーション起動後に発生したすべての invoke イベントを受け取ります。

1 つの AIR アプリケーションについて、起動されるインスタンスは 1 つだけです。既に実行されているアプリケーションが再び呼び出されると、AIR は実行中のインスタンスに対して新しい invoke イベントを送出します。invoke イベントに応答し、適切なアクションを実行する(例えば新しいドキュメントウィンドウを開く)ことは、AIR アプリケーションの役割です。

InvokeEvent オブジェクトには、アプリケーションと、そのアプリケーションが呼び出されたディレクトリに渡された任意の引数が格納されます。アプリケーションがファイルの種類による関連付けによって呼び出された場合には、コマンドライン引数にそのファイルへのフルパスが含まれます。同様に、アプリケーションがアプリケーションアップデートのために呼び出された場合には、アップデート AIR ファイルへのフルパスが設定されます。

アプリケーションが invoke イベントを処理できるようにするには、その NativeApplication オブジェクトにリスナーを次のように登録します。

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

さらに、イベントリスナーを次のように定義します。

var arguments; 
var currentDir; 
function onInvokeEvent(invocation) { 
    arguments = invocation.arguments; 
    currentDir = invocation.currentDirectory; 
}

コマンドライン引数のキャプチャ

AIR アプリケーションの呼び出しに関連するコマンドライン引数は、NativeApplication オブジェクトによって送出される invoke イベントで送出されます。InvokeEvent.arguments プロパティには、AIR アプリケーションの呼び出し時にオペレーティングシステムによって渡される引数の配列が格納されています。引数にファイルの相対パスが含まれている場合、パスを解決するには、通常は currentDirectory プロパティを使用します。

AIR プログラムに渡される引数は、次の表に示すように、二重引用符で囲まれている場合を除いて、空白で区切られたストリングとして扱われます。

引数

配列

tick tock

{tick,tock}

tick "tick tock"

{tick,tick tock}

"tick" “tock”

{tick,tock}

\"tick\" \"tock\"

{"tick","tock"}

InvokeEvent.currentDirectory プロパティには、そのアプリケーションが起動されたディレクトリを表す File オブジェクトが格納されます。

アプリケーションが、そのアプリケーションによって登録された種類のファイルが開かれたことによって呼び出された場合には、そのファイルへのネイティブパスがコマンドライン引数にストリングとして設定されます(ファイルを開いたり、ファイルに対して目的の操作を実行することは、アプリケーションの役割です)。同様に、アプリケーションがアップデートを自動で(標準の AIR アップデートユーザインターフェイスを使用せずに)実行するようにプログラムされている場合には、一致するアプリケーション ID を持つアプリケーションを格納した AIR ファイルをユーザがダブルクリックしたときに、AIR ファイルへのネイティブパスが設定されます。

ファイルにアクセスするには、currentDirectory File オブジェクトの resolve() メソッドを次のように使用します。

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

引数が本当にファイルへのパスであるかどうかについても検証する必要があります。

例:呼び出しイベントログ

次の例では、invoke イベントに対するリスナーを登録し、このイベントを処理する方法を示します。この例では、受け取ったすべての呼び出しイベントを記録し、現在のディレクトリとコマンドライン引数を表示します。

注意: この例では、AIRAliases.js ファイルを使用しています。このファイルは、SDK のフレームワークフォルダにあります。
<html> 
<head> 
<title>Invocation Event Log</title> 
<script src="AIRAliases.js" /> 
<script type="text/javascript">  
function appLoad(){ 
    air.trace("Invocation Event Log."); 
    air.NativeApplication.nativeApplication.addEventListener( 
        air.InvokeEvent.INVOKE, onInvoke); 
    } 
} 
     
function onInvoke(invokeEvent){ 
    logEvent("Invoke event received."); 
    if (invokeEvent.currentDirectory) { 
        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--"); 
    } 
} 
     
function logEvent(message){ 
    var logger = document.getElementById('log'); 
    var line = document.createElement('p'); 
    line.innerHTML = message; 
    logger.appendChild(line); 
    air.trace(message); 
} 
 
window.unload = function() { 
        air.NativeApplication.nativeApplication.removeEventListener( 
            air.InvokeEvent.INVOKE, onInvoke); 
} 
</script> 
</head> 
 
<body onLoad="appLoad();"> 
    <div id="log"/> 
</body> 
</html>

ログイン時の起動

AIR アプリケーションが、現在のユーザがログインしたときに自動的に起動するように設定するには、NativeApplication.nativeApplication.startAtLogin=true と設定します。このように設定すると、アプリケーションはユーザがログインすると自動的に起動します。起動時にアプリケーションが自動起動しないようにするには、設定を false に変更するか、ユーザが設定をオペレーティングシステムから手動で変更するか、またはアプリケーションをアンインストールします。ログイン時の起動は、実行時設定です。

注意: アプリケーションは、コンピュータシステムの起動時には起動しません。アプリケーションは、ユーザのログイン時に起動します。この設定は、現在のユーザにのみ適用されます。また、startAtLogin プロパティを true に設定するには、アプリケーションがインストールされている必要があります。アプリケーションがインストールされていない(例えば ADL で起動される)場合、プロパティを設定するとエラーがスローされます。

ブラウザによる呼び出し

ブラウザ呼び出し機能を使用すると、Web サイトでは、インストールされている AIR アプリケーションをブラウザから起動されるように起動できます。ブラウザによる呼び出しは、アプリケーション記述ファイルで allowBrowserInvocation が次のように true に設定されている場合にのみ許可されます。

<allowBrowserInvocation>true</allowBrowserInvocation>

アプリケーション記述ファイルについて詳しくは、AIR アプリケーションプロパティの設定を参照してください。

アプリケーションがブラウザによって呼び出されると、アプリケーションの NativeApplication オブジェクトは BrowserInvokeEvent オブジェクトを送出します。

BrowserInvokeEvent イベントを受け取るには、AIR アプリケーションの NativeApplication オブジェクト(NativeApplication.nativeApplication)の addEventListener() メソッドを呼び出します。イベントリスナーは、BrowserInvokeEvent イベントについて登録されると、登録前に発生したすべての BrowserInvokeEvent イベントも受け取ります。これらのイベントは、addEventListener() に対する呼び出しが返された後で送出されますが、登録後に受け取られる可能性のある他の BrowserInvokeEvent イベントよりも前とは限りません。これにより、初期化コードが実行される前(例えばアプリケーションがブラウザから最初に呼び出されたとき)に発生した BrowserInvokeEvent イベントを処理できます。イベントリスナーは、実行の比較的遅い時点(アプリケーション初期化の後)で追加された場合でも、アプリケーション起動後に発生したすべての BrowserInvokeEvent イベントを受け取ります。

BrowserInvokeEvent オブジェクトには、次のプロパティが含まれます。

プロパティ

説明

arguments

アプリケーションに渡す引数(ストリング)の配列。

isHTTPS

ブラウザ内のコンテンツが https URL スキームを使用する(true)か、使用しない(false)かを指定します。

isUserEvent

ブラウザによる呼び出しがユーザイベント(例えばマウスクリック)で発生したかどうかを示します。AIR 1.0 では、このプロパティは常に true に設定されます。AIR では、ブラウザ呼び出し機能に対するユーザイベントが必要です。

sandboxType

ブラウザ内のコンテンツに対して使用するサンドボックスのタイプ。有効値の定義は、Security.sandboxType プロパティで使用できる有効値の場合と同じで、次のいずれかです。

  • Security.APPLICATION — コンテンツは、アプリケーションセキュリティサンドボックスで実行されます。

  • Security.LOCAL_TRUSTED — コンテンツは、local-with-filesystem セキュリティサンドボックスで実行されます。

  • Security.LOCAL_WITH_FILE — コンテンツは、local-with-filesystem セキュリティサンドボックスで実行されます。

  • Security.LOCAL_WITH_NETWORK — コンテンツは、local-with-networking セキュリティサンドボックスで実行されます。

  • Security.REMOTE — コンテンツは、リモート(ネットワーク)ドメインで実行されます。

securityDomain

ブラウザ内のコンテンツのセキュリティドメイン。例えば「www.adobe.com」や「www.example.org」など。このプロパティは、リモートのセキュリティサンドボックスで実行されるコンテンツ(ネットワークドメインからのコンテンツ)に対してのみ設定されます。ローカルまたはアプリケーションセキュリティサンドボックスで実行されるコンテンツに対しては設定されません。

ブラウザ呼び出し機能を使用する場合は、セキュリティ上の影響を考慮してください。Web サイトで AIR アプリケーションが起動されると、アプリケーションは BrowserInvokeEvent オブジェクトの arguments プロパティを介してデータを送信できます。このデータを、ファイルやコードを読み込む API のような注意を必要とする操作で使用する場合には、慎重に行う必要があります。リスクのレベルは、アプリケーションがそのデータを使用して実行する処理の種類によって異なります。アプリケーションが特定の Web サイトだけで呼び出されることを想定している場合、そのアプリケーションは BrowserInvokeEvent オブジェクトの securityDomain プロパティを検査する必要があります。また、そのアプリケーションを呼び出す Web サイトに対して、HTTPs を使用するように要求することもできます。これは、BrowserInvokeEvent オブジェクトの isHTTPS プロパティを検査することで検証できます。

アプリケーションは、渡されたデータを検証する必要があります。例えば、あるアプリケーションが特定のドメインの URL を渡されることを予期している場合、そのアプリケーションは、その URL が本当にそのドメインを指し示しているかどうかを検証する必要があります。これにより、攻撃者がアプリケーションを不正に操作して重要なデータを送信させることを防ぐことができます。

ローカルのリソースを指し示す可能性のある BrowserInvokeEvent 引数を、アプリケーションで使用しないでください。例えば、アプリケーションでは、ブラウザから渡されたパスに基づいて File オブジェクトを作成することは避けてください。ブラウザからリモートのパスが渡されることを想定している場合、アプリケーションでは、リモートプロトコルの代わりに file:// プロトコルがパスに使用されていないことを確認する必要があります。

ブラウザからのアプリケーションの呼び出しについて詳しくは、ブラウザからインストールされた AIR アプリケーションの起動を参照してください。

アプリケーションの終了

アプリケーションを最もすばやく終了する方法は、NativeApplication.nativeApplication.exit() を呼び出すことです。これは、アプリケーションに保存するデータやクリーンアップするリソースがない場合に適した方法です。exit() を呼び出すと、すべてのウィンドウが閉じ、アプリケーションが終了します。しかし、例えば重要なデータを保存するために、アプリケーションのウィンドウやその他のコンポーネントが終了プロセスを中断できるようにする場合は、exit() を呼び出す前に、適切な警告イベントを送出します。

アプリケーションを適切な手順に従ってシャットダウンするためのもう一つの方法は、シャットダウンプロセスを開始する方法とは関係なく、単一の実行経路を設定することです。ユーザ(またはオペレーティングシステム)は、次に示す方法でアプリケーションの終了をトリガすることができます。

  • NativeApplication.nativeApplication.autoExittrue の場合に、最後のアプリケーションウィンドウを閉じる。

  • オペレーティングシステムから、アプリケーション終了コマンドを選択する(例えば、ユーザがデフォルトのメニューからアプリケーションを終了するコマンドを選択した場合)。これは Macintosh でのみ可能です。Windows では、システムクロムによるアプリケーション終了コマンドは提供されていません。

  • コンピュータをシャットダウンする。

終了コマンドがオペレーティングシステムを介して、これらのいずれかの方法で渡されると、NativeApplication は exiting イベントを送出します。リスナーが exiting イベントをキャンセルしなければ、開いているすべてのウィンドウが閉じられます。各ウィンドウは closing イベントを送出し、次に close イベントを送出します。いずれかのウィンドウで closing イベントがキャンセルされると、シャットダウンプロセスは停止します。

アプリケーションで、ウィンドウを閉じる順序が重要である場合には、NativeApplication からの exiting イベントをリッスンし、ユーザ自身がウィンドウを正しい順序で閉じます。例えば、ツールパレットの付いたドキュメントウィンドウを閉じる場合がこれに該当します。システムがパレットを閉じたが、ユーザはデータを保存するために終了コマンドをキャンセルすることにした、というような場合には、これは非常に不便です。Windows では、exiting イベントを受け取る唯一の機会は、最後のウィンドウを閉じた後です(NativeApplication オブジェクトの autoExit プロパティが true に設定されている場合)。

すべてのプラットフォームで一貫性のある動作を実現するためには、終了シーケンスがオペレーティングシステムクロム、メニューコマンド、アプリケーションロジックのいずれから開始される場合でも、アプリケーションを終了するための、次に示す正しい方法を遵守してください。

  1. 常に exiting イベントを NativeApplication オブジェクトから、アプリケーションコードで exit() を呼び出す前に送出し、アプリケーションの他のコンポーネントがこのイベントをキャンセルしていないことを確認します。

    function applicationExit(){ 
        var exitingEvent = new air.Event(air.Event.EXITING, false, true); 
        air.NativeApplication.nativeApplication.dispatchEvent(exitingEvent); 
        if (!exitingEvent.isDefaultPrevented()) { 
            air.NativeApplication.nativeApplication.exit(); 
        } 
    }
  2. NativeApplication.nativeApplication オブジェクトから送出されたアプリケーションの exiting イベントをリッスンし、ハンドラですべてのウィンドウを閉じます(最初に closing イベントを送出します)。すべてのウィンドウが閉じたら、アプリケーションデータの保存や一時ファイルの削除などの必要なクリーンアップタスクを実行します。クリーンアップでは同期メソッドのみを使用することで、アプリケーションの終了前にそれらのメソッドが必ず終了するようにします。

    ウィンドウを閉じる順序が重要でない場合は、NativeApplication.nativeApplication.openedWindows 配列をループし、各ウィンドウを順次閉じていきます。順序が重要である場合には、ウィンドウを正しい順序で閉じる手段を提供します。

    function onExiting(exitingEvent) { 
        var winClosingEvent; 
        for (var i = 0; i < air.NativeApplication.nativeApplication.openedWindows.length; i++) { 
            var win = air.NativeApplication.nativeApplication.openedWindows[i]; 
            winClosingEvent = new air.Event(air.Event.CLOSING,false,true); 
            win.dispatchEvent(winClosingEvent); 
            if (!winClosingEvent.isDefaultPrevented()) { 
                win.close(); 
            } else { 
                exitingEvent.preventDefault(); 
            } 
        } 
         
        if (!exitingEvent.isDefaultPrevented()) { 
            //perform cleanup 
        } 
    }
  3. 各ウィンドウは、それ自身の closing イベントをリッスンすることで、常にそれ自身のクリーンアップを処理する必要があります。

  4. アプリケーションでは、使用する exiting リスナーを 1 つだけにします。これは、以前に呼び出されたハンドラは、後続のハンドラが exiting イベントをキャンセルするかどうかを知ることができないためです(また、実行の順序に依拠することも賢明ではありません)。