2

アプリケーションにプラグイン システムを実装しようとしていますが、動的にロードされた SWF ファイルを取得するのに時間がかかり、追加の SWF ファイルをロードします。

次のようになります。

  1. メイン アプリケーション シェルの読み込み...
  2. ------+ アプリケーションのロード...
  3. -----------------+プラグイン

アプリ #1 を取得してアプリ #2 を読み込むことに問題はありません

ただし、試してみると、アプリ#2をロードして#3をインスタンス化できません

ModuleManager を使用してさまざまな順列を試しましたが、これが最も近いものです。onLoadComplete メソッドが呼び出されると、SWF がロードされたことがわかりますが、ファクトリは常に NULL を返します。

興味深いのは、これを独自のアプリケーションで抽出すると、正常に動作することです。この問題は、動的にロードされた SWF からプラグインをロードしているという事実によって引き起こされます。

これは によるものApplicationDomainだと思いますが、表も裏もわかりません。を指定してみましたcurrentDomainが、成功 new ApplicationDomain(Application.currentDomain)しませんでした。new ApplicationDomain()

また、どちらのアプリケーションでも Foo クラスへの参照をハード参照にすることはできないことに注意することも重要です。これは、その性質上、何が含まれるかを事前に知ることができないためです。

グーグルで調べてみると、これはよく知られている問題のようですが、まだ (明確な) 解決策を見つけていません。

.
.
.
assetModule = ModuleManager.getModule("Foo.swf");    
assetModule.addEventListener(ModuleEvent.READY, onLoadComplete );
assetModule.addEventListener(ModuleEvent.ERROR, onLoadError);
assetModule.load();
.
.
.
private var _pluginInstance:Plugin;

private function onLoadComplete( event:Event ):void
{
    trace("module loaded");

    _pluginInstance = assetModule.factory.create() as Plugin;
    if( _pluginInstance )
        _pluginInstance.startup();
    else 
        Alert.show("unable to instantiate module");
}

private function onLoadError( event:Event ):void
{
       Alert.show("error");
}

My Plugin looks like this:

package
{
    import mx.collections.ArrayCollection;
    import mx.modules.ModuleBase;

        public class Plugin extends ModuleBase

        public function startup():void
        {

        }
.
.
.
}

package 
{
    import Plugin;
    import mx.modules.ModuleBase;

    public class Foo extends Plugin
    {
        public function Foo()
        {
            trace("foo constructor invoked");
        }

        override public function startup():void
        {
                    trace("foo started");
        }
.
.
.
}
4

2 に答える 2

0

プラグインとアプリケーションの間で共通のインターフェースを使用したい場合、アプリケーションの Plugin クラスはプラグインの Plugin クラスと同じでなければなりません。そのためには、b が同じ ApplicationDomain にある必要があります。

//In an external library
public interface Plugin {}

//In your application
_pluginInstance = assetModule.factory.create() as Plugin;
...


//In your plugin
public class MyPlugin implements Plugin

問題は、プラグイン swf をコンパイルするときに、プラグインもコンパイルすることです。これは問題ではありませんが、自分の と同じであることをアプリケーションに伝える必要があります。

var loader:Loader = new Loader();
loader.addEventListener(Event.COMPLETE, onLoadComplete);
loader.load(new URLRequest("plugin.swf"), new LoaderContext(false, ApplicationDomain.currentDomain));    

ApplicationDomain.currentDomain がここでの鍵です。ドキュメントを参照する場合:

ローダー独自の ApplicationDomain。ApplicationDomain.currentDomain を使用する場合は、このアプリケーション ドメインを使用します。ロードが完了すると、親と子は互いのクラスを直接使用できます。親によってすでに定義されているクラスと同じ名前のクラスを子が定義しようとすると、親クラスが使用され、子クラスは無視されます。

于 2009-07-04T21:42:38.370 に答える