前回まででの2回で、モジュールを使って Flex アプリケーションを細かなモジュールに分割する方法を説明ました。しかし、異なる SWF ファイルを扱うとなると、非同期処理も絡んできますし、同じライブラリが両方の SWF に含まれると全体のサイズも大きくなります。
そこで、今回は1つの SWF ファイルに複数モジュールを作成して、遅延ローディングする方法をご説明します。
通常、Flex の SWF では、ローディング用画面が1フレーム目、Flex の本体が2フレーム目に配置されます。
しかし、コンパイルオプションに、-frame=label,ClassName と指定することにより、ClassName で指定したクラスを3フレーム目以降に配置することができます。
Flash Player は1フレーム目から順次ロードして行き、ロード完了した順番に表示していきます。そのため、2フレーム目までのロードが完了した時点で、Flex アプリケーションが表示されます。3フレーム目以降に容量の大きなモジュールを配置しておけば、モジュールの遅延ロードが可能となります。しかも、全体で1つの SWF ファイルですから、管理も楽です。
モジュールの実装方法は以下のようになります。
public class MyModule implements IFlexModuleFactory{
[Embed(source='my_music.mp3')]
private var MyMusic:Class;
public function getMyMusic():Object{
return new MyMusic();
}
public static function frame(factory:IFlexModuleFactory):void{
ModuleManager.getModule( "published://ModuleName" ).publish(new MyModule()); }
}
モジュールクラスでは IFlexModuleFactory を継承しておいて、static な frame() メソッドを作成します。frame() メソッド内では、published://ModuleName という URL に自分自身のインスタンスを登録しています。
ロードする側では次のようにします。
var module:IModuleInfo = ModuleManager.getModule( "published://ModuleName");
module.addEventListener(ModuleEvent.READY, function(e:ModuleEvent):void {
varsound:Sound = module.factory.getMyMusic() as Sound;
});
3フレーム目のロードが完了した時点で、published://ModuleName の準備が完了し、ModuleEvent.READY イベントが発行されます。このタイミングで遅延ロードした my_music.mp3 を利用できるというわけです。
コンパイル時に、-frame=label,MyModule と指定するのをお忘れなく。
詳しくは、Roger Gonzalez: My MAX preso... の demos\venice\VeniceStreamed\src を見るとよいでしょう。
ところで、モジュールの frame() メソッドは誰が呼んでいるのでしょうか。実は、Flex フレームワーク自身が呼び出しています。もう少し具体的に言うと、SystemManager クラスの extraFrameHandler() メソッドが呼び出します。この部分についても、軽く解説したいのですが、続きは次回といたしましょう。