Создание плагинов во Flex - загрузка вложенных SWF-файлов - PullRequest
2 голосов
/ 27 апреля 2009

Я пытаюсь внедрить систему плагинов для нашего приложения и, черт побери, получаю SWF-файл, который сам по себе динамически загружался, загружаю дополнительные SWF-файлы.

Это выглядит примерно так:

  1. Основное приложение Shell загружает ...
  2. --------- + Приложение загружается ...
  3. ----------------- + плагин (ы)

У меня нет проблем с получением приложения № 1 для загрузки приложения № 2

Однако, как бы я ни пытался, я не могу загрузить приложение № 2 и создать экземпляр # 3

Я пробовал различные перестановки с использованием ModuleManager, но это самое близкое, что я получил. Когда вызывается метод onLoadComplete, я вижу, что SWF загружен, однако фабрика всегда возвращает NULL.

Что интересно, когда я извлекаю это в собственном приложении, оно работает нормально. Эта проблема вызвана тем, что я загружаю плагин из SWF-файла, который был загружен сам по себе.

Я верю, что это из-за ApplicationDomain, но я не могу сделать из этого ни головы, ни хвоста. Я попытался указать currentDomain, new ApplicationDomain(Application.currentDomain) и new ApplicationDomain() безуспешно.

Также важно отметить, что я не могу сделать жесткую ссылку на класс Foo ни в одном приложении, так как по своей природе мы не будем заранее знать, что они будут содержать.

Googlin 'вокруг, это, кажется, довольно известная проблема, но я еще не нашел (ясного) решения.

.
.
.
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");
        }
.
.
.
}

Ответы [ 2 ]

0 голосов
/ 05 июля 2009

Если вы действительно хотите использовать общий интерфейс между вашим плагином и приложением, класс плагинов вашего приложения должен совпадать с классом плагинов вашего плагина. Для этого им нужно, чтобы b находился в одном домене приложения.

//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. когда загрузка завершена, родитель и потомок могут использовать классы друг друга напрямую. Если ребенок пытается определить класс с тем же именем, что и класс уже определено родителем, родительский класс используется и дочерний класс игнорируется.

0 голосов
/ 03 июня 2009

@ Джоштыняла прав. Я нашел попробуйте просто использовать Object, а затем вызывать методы (не приводить).

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

Как правило, без проблем можно привести между классами system / flex. Не знаете, поможет ли установка плагина в качестве библиотеки времени выполнения?

...