我正在尝试为我们的应用程序实现一个插件系统,并且有一段时间获取自动动态加载的SWF文件,加载其他SWF文件。
它是这样的:
我没有问题让app#1加载app#2
但是,尽我所能,我无法让app#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");
}
.
.
.
}
答案 0 :(得分:0)
@ joshtynjala是对的。我发现尝试只使用Object然后调用它的方法(不要强制转换)。
var MyPlugin:Object = getPlugin(); MyPlugin.doPluginFunc();
一般可以在系统/ flex类之间强制转换没问题。不知道将Plugin作为运行时库是否有帮助?
答案 1 :(得分:0)
如果您真的想在插件和应用程序之间使用通用接口,那么您的应用程序的插件类必须与插件的插件类相同。为此,他们需要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是这里的关键。如果您参考docs:
Loader自己的ApplicationDomain。您 使用时使用此应用程序域 ApplicationDomain.currentDomain来。什么时候 负载是完整的,父母和孩子 可以直接使用彼此的类。 如果孩子试图定义一个 与类同名的类 已经由父母定义了 使用父类和孩子 class被忽略了。