Flex アプリケーションでモジュールをロードおよびアンロードするために使用できるいくつかの手法があります。これらの手法には次のようなものがあります。
AIR アプリケーション内でモジュールを使用している場合、モジュールの SWF はメインアプリケーションの SWF かそのサブディレクトリのいずれかと同じディレクトリ内に置く必要があります。
ModuleLoader クラスを使用すると、モジュールをアプリケーションや他のモジュールにロードできます。MXML アプリケーションでこれを最も簡単に行うには、<mx:ModuleLoader> タグを使用します。url プロパティの値を設定して、モジュールの SWF ファイルの場所を指定します。次の例では、アプリケーションの最初の起動時にモジュールをロードしています。
<?xml version="1.0"?>
<!-- modules/MySimplestModuleLoader.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:ModuleLoader url="ColumnChartModule.swf"/>
</mx:Application>
前の例で実行する SWF ファイルは以下のとおりです。
モジュールをロードするタイミングは、イベントに応答する時点などで url プロパティの値を設定することにより変更できます。
ModuleLoader のターゲット URL を設定すると、loadModule() メソッドへの呼び出しがトリガされます。この呼び出しは、設定された url プロパティを使用して ModuleLoader を初めて作成したときに発生します。また、そのプロパティの値を変更したときにも発生します。
url プロパティの値を空のストリング("")に設定すると、現在のモジュールがアンロードされます。
1 つのアプリケーションには複数の ModuleLoader インスタンスを配置できます。次の例では、TabNavigator コンテナの該当するタブにユーザーが移動したときにモジュールをロードしています。
<?xml version="1.0"?>
<!-- modules/URLModuleLoaderApp.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Panel
title="Module Example"
height="90%"
width="90%"
paddingTop="10"
paddingLeft="10"
paddingRight="10"
paddingBottom="10"
>
<mx:Label width="100%" color="blue"
text="Select the tabs to change the panel."/>
<mx:TabNavigator id="tn"
width="100%"
height="100%"
creationPolicy="auto"
>
<mx:VBox id="vb1" label="Column Chart Module">
<mx:Label id="l1" text="ColumnChartModule.swf"/>
<mx:ModuleLoader url="ColumnChartModule.swf"/>
</mx:VBox>
<mx:VBox id="vb2" label="Bar Chart Module">
<mx:Label id="l2" text="BarChartModule.swf"/>
<mx:ModuleLoader url="BarChartModule.swf"/>
</mx:VBox>
</mx:TabNavigator>
</mx:Panel>
</mx:Application>
前の例で実行する SWF ファイルは以下のとおりです。
また、ModuleLoader API を使用して、loadModule() メソッドと unloadModule() メソッドを使用してもモジュールをロードおよびアンロードできます。これらのメソッドはパラメータを受け取りません。ModuleLoader は、現在の url プロパティと値が一致するモジュールをロードまたはアンロードします。
次の例では、ボタンをクリックしたときに、モジュールをロードまたはアンロードします。
<?xml version="1.0"?>
<!-- modules/ASModuleLoaderApp.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
import mx.modules.*;
public function createModule(m:ModuleLoader, s:String):void {
if (!m.url) {
m.url = s;
return;
}
m.loadModule();
}
public function removeModule(m:ModuleLoader):void {
m.unloadModule();
}
]]>
</mx:Script>
<mx:Panel title="Module Example"
height="90%"
width="90%"
paddingTop="10"
paddingLeft="10"
paddingRight="10"
paddingBottom="10"
>
<mx:TabNavigator id="tn"
width="100%"
height="100%"
creationPolicy="auto"
>
<mx:VBox id="vb1" label="Column Chart Module">
<mx:Button
label="Load"
click="createModule(chartModuleLoader, l1.text)"
/>
<mx:Button
label="Unload"
click="removeModule(chartModuleLoader)"
/>
<mx:Label id="l1" text="ColumnChartModule.swf"/>
<mx:ModuleLoader id="chartModuleLoader"/>
</mx:VBox>
<mx:VBox id="vb2" label="Form Module">
<mx:Button
label="Load"
click="createModule(formModuleLoader, l2.text)"
/>
<mx:Button
label="Unload"
click="removeModule(formModuleLoader)"
/>
<mx:Label id="l2" text="FormModule.swf"/>
<mx:ModuleLoader id="formModuleLoader"/>
</mx:VBox>
</mx:TabNavigator>
</mx:Panel>
</mx:Application>
前の例で実行する SWF ファイルは以下のとおりです。
モジュールをロードするとき、そのモジュールの load() メソッドを何回呼び出したかにかかわらず、Flex では必ず 1 つのモジュールのコピーだけがロードされます。
名前が同じで実装が異なる 2 つのクラスをロードする場合、最初にロードされたクラスが使用されるクラスとなります。これが原因で、ランタイムエラーが発生することがあります。複数のモジュールを使用するときに発生する一般的な問題は、他のモジュールで使用する必要があるクラス定義をモジュールが所有することです。クラス定義は子アプリケーションドメインにあるので、最初にクラス定義をロードしたモジュールはそのクラスを使用できますが、他のモジュールがそのクラスを使用しようとするとエラーが発生します。この解決方法は、クラス定義をメインアプリケーションドメインに格上げして、すべてのモジュールでそのクラスを使用できるようにすることです。詳細については、モジュールのドメインを参照してください。
ModuleManager クラスを使用してモジュールをロードできます。この手法は <mx:ModuleLoader> タグを使用するよりも抽象性は減少しますが、モジュールをロードする方法やその時期をより詳細に制御できます。
ModuleManager を使用して ActionScript にモジュールをロードするには、まず ModuleManager の getModule() メソッドを使用して、モジュールの IModuleInfo インタフェースの参照を取得します。次に、そのインターフェイスの load() メソッドを呼び出します。最後に、そのインターフェイスの factory プロパティを使用して create() メソッドを呼び出し、戻り値をモジュールのクラスとしてキャストします。
IModuleInfo クラスの load() メソッドでは、オプションで引数として ApplicationDomain および SecurityDomain を指定できます。これらのどちらも指定しない場合、モジュールは新しい子ドメイン内にロードされます。
次の例では、シェルアプリケーションで ColumnChartModule.swf ファイルをロードし、そのファイルを表示リストに追加して、アプリケーションの起動時にそのファイルが表示されるようにしています。
<?xml version="1.0"?>
<!-- modules/ModuleLoaderApp.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="initApp()">
<mx:Script>
<![CDATA[
import mx.events.ModuleEvent;
import mx.modules.ModuleManager;
import mx.modules.IModuleInfo;
public var info:IModuleInfo;
private function initApp():void {
info = ModuleManager.getModule("ColumnChartModule.swf");
info.addEventListener(ModuleEvent.READY, modEventHandler);
// Load the module into memory. Calling load() makes the
// IFlexModuleFactory available. You can then get an
// instance of the class using the factory's create()
// method.
info.load();
}
private function modEventHandler(e:ModuleEvent):void {
// Add an instance of the module's class to the
// display list.
vb1.addChild(info.factory.create() as ColumnChartModule);
}
]]>
</mx:Script>
<mx:VBox id="vb1"/>
</mx:Application>
前の例で実行する SWF ファイルは以下のとおりです。
MXML ベースのモジュールは、他のモジュールをロードすることができます。さらに、それらのモジュールが他のモジュールをロードし、それを続けることができます。
モジュールインスタンスは、関数のローカルスコープ内に含まれないように、関数の外側で定義してください。これに従わないと、オブジェクトがガベージコレクションされたり、関連するイベントリスナーが呼び出されなかったりする場合があります。
あるサーバーから、異なるサーバー上で実行されているアプリケーションにモジュールをロードするには、モジュールとそのモジュールをロードするアプリケーションとの間に、信頼関係を確立する必要があります。
次の例は、ロード元のアプリケーションの init() メソッドを示しています。
public function setup():void {
Security.allowDomain("remoteservername");
Security.loadPolicyFile("http://remoteservername/crossdomain.xml");
var request:URLRequest = new URLRequest("http://remoteservername/crossdomain.xml");
var loader:URLLoader = new URLLoader();
loader.load(request);
}
次の例は、ロードされたモジュールの init() メソッドを示しています。
public function initMod():void {
Security.allowDomain("loaderservername");
}
次の例は、リモートサーバーに存在するクロスドメインファイルを示しています。
<!-- crossdomain.xml file located at the root of the server -->
<cross-domain-policy>
<allow-access-from domain="loaderservername" to-ports="*"/>
</cross-domain-policy>
クロスドメインポリシーファイルの使用の詳細について、『Adobe Flex 3 アプリケーションの構築とデプロイ』のFlex へのセキュリティの適用
モジュールを使用するアプリケーションを最初に起動したときには、アプリケーションのファイルサイズはモジュールを使用していない類似のアプリケーションよりも小さくなります。このため、モジュールの SWF ファイルがネットワーク経由で転送される前にアプリケーションをメモリ内にロードして Flash Player 内または AIR 内で実行できるので、待ち時間が短縮されます。ただし、モジュールを使用しているアプリケーションの部分にユーザーが移動したときは、遅延が生じます。これは、モジュールはデフォルトではプリロードされるのではなく、最初に要求されたときにロードされるからです。
モジュールが Flex アプリケーションによって最初にロードされたときに、そのモジュールの SWF ファイルがネットワーク経由で転送されてブラウザのキャッシュに格納されます。Flex アプリケーションがモジュールをアンロードした後にリロードする場合、Flash Player はネットワーク経由ではなくキャッシュからモジュールをロードするので、待ち時間が短縮されます。
モジュールの SWF ファイルは、ユーザーがキャッシュをクリアしない限り、すべての SWF ファイルが同様にブラウザのキャッシュに残ります。したがって、メインアプリケーションでは複数のセッションに渡り、ロード時間を短縮してモジュールをロードできます。ただし、これは、ブラウザのキャッシュがフラッシュされる頻度に依存します。
モジュールはいつでもプリロードできるので、モジュールが現在使用されていない場合でもモジュールの SWF ファイルをメモリ内に配置しておくことができます。
アプリケーションの起動時にモジュールをプリロードするには、IModuleInfo クラスの load() メソッドを使用します。このメソッドはモジュールをメモリ内にロードしますが、モジュールのインスタンスは作成されません。
次の例では、アプリケーションの起動時に BarChartModule.swf モジュールをロードしていますが、このモジュールは、TabNavigator の 2 番目のペインにユーザーが移動するまでは表示されません。プリロードを使用しない場合、ユーザーは、TabNavigator の 2 番目のペインに移動したときに、ネットワーク経由で SWF ファイルが転送されるのを待つことになります。
<?xml version="1.0"?>
<!-- modules/PreloadModulesApp.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="preloadModules()">
<mx:Script>
<![CDATA[
import mx.events.ModuleEvent;
import mx.modules.ModuleManager;
import mx.modules.IModuleInfo;
private function preloadModules():void {
// Get a reference to the module's interface.
var info:IModuleInfo =
ModuleManager.getModule("BarChartModule.swf");
info.addEventListener(ModuleEvent.READY, modEventHandler);
// Load the module into memory. The module will be
// displayed when the user navigates to the second
// tab of the TabNavigator.
info.load();
}
private function modEventHandler(e:ModuleEvent):void {
trace("module event: " + e.type); // "ready"
}
]]>
</mx:Script>
<mx:Panel
title="Module Example"
height="90%"
width="90%"
paddingTop="10"
paddingLeft="10"
paddingRight="10"
paddingBottom="10"
>
<mx:Label width="100%" color="blue"
text="Select the tabs to change the panel."/>
<mx:TabNavigator id="tn"
width="100%"
height="100%"
creationPolicy="auto"
>
<mx:VBox id="vb1" label="Column Chart Module">
<mx:Label id="l1" text="ColumnChartModule.swf"/>
<mx:ModuleLoader url="ColumnChartModule.swf"/>
</mx:VBox>
<mx:VBox id="vb2" label="Bar Chart Module">
<mx:Label id="l2" text="BarChartModule.swf"/>
<mx:ModuleLoader url="BarChartModule.swf"/>
</mx:VBox>
</mx:TabNavigator>
</mx:Panel>
</mx:Application>
前の例で実行する SWF ファイルは以下のとおりです。
このページに新しいコメントが追加された場合に、電子メールでの通知を希望する。 | コメントレポート