【问题标题】:Create Plugins in Flex - loading nested SWF files在 Flex 中创建插件 - 加载嵌套的 SWF 文件
【发布时间】:2010-10-22 01:15:10
【问题描述】:

我正在尝试为我们的应用程序实现一个插件系统,并且非常想获得自己动态加载的 SWF 文件,加载其他 SWF 文件。

它是这样的:

  1. 主要应用程序外壳加载...
  2. ---------+ 应用程序加载...
  3. -----------------+插件

让应用程序 #1 加载应用程序 #2 没有问题

但是,尽我所能,我无法让应用 #2 加载和实例化 #3

我使用 ModuleManager 尝试了各种排列,但这是我得到的最接近的。当调用 onLoadComplete 方法时,我可以看到 SWF 已加载,但工厂始终返回 NULL。

有趣的是,当我将其提取到它自己的应用程序中时,它运行良好。这个问题是由我从一个本身动态加载的 SWF 加载插件这一事实触发的。

我相信这是由于ApplicationDomain,但我无法确定它的正面或反面。我尝试指定currentDomainnew 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");
        }
.
.
.
}

【问题讨论】:

  • 我很久没有使用应用程序域了,所以我无法为您的问题提供完整的答案,但我可以告诉您问题出在此处:assetModule.factory。 create() 作为插件;就 VM 而言,模块中的 Plugin 类和主应用程序中的 Plugin 类是不一样的。使用“as Plugin”进行强制转换会返回 null,因为 Plugin != Plugin。如何解决这个问题(除了将其转换为 Object 或其他东西),我不记得了,但您正在调查 ApplicationDomain 类的正确轨道。

标签: apache-flex actionscript-3 plugins applicationdomain


【解决方案1】:

如果你真的想在你的插件和你的应用程序之间使用一个通用接口,你的应用程序的 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 时,你也会编译 Plugin。这不是问题,但是您需要告诉您的应用程序它与他的相同:

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

ApplicationDomain.currentDomain 是这里的关键。如果参考docs

Loader 自己的 ApplicationDomain。你 使用时使用此应用程序域 应用程序域。当前域。什么时候 加载完成,父子 可以直接使用彼此的类。 如果孩子试图定义一个 与类同名的类 已经由父级定义, 使用父类和子类 类被忽略。

【讨论】:

    【解决方案2】:

    @joshtynjala 是对的。我发现尝试只使用 Object 然后在其上调用方法(不要强制转换)。

    var MyPlugin : Object = getPlugin(); MyPlugin.doPluginFunc();

    一般可以在 system/flex 类之间转换没问题。不知道将 Plugin 作为运行时库是否有帮助?

    【讨论】:

      猜你喜欢
      • 2010-10-10
      • 1970-01-01
      • 1970-01-01
      • 2010-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多