2009-04-27 1 views
2

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

Это идет что-то вроде этого:

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

у меня нет никаких проблем получать приложение № 1, чтобы загрузить приложение # 2

Однако, попробуйте как я мог, я не могу получить приложение # 2 для загрузки и stantiate # 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"); 
     } 
. 
. 
. 
} 
+1

Я не работал с доменами приложений в течение длительного времени, поэтому я не могу дать полный ответ на ваш вопрос, но я могу вам сказать, что проблема здесь происходит: assetModule.factory.create() как плагин; Класс Plugin в вашем модуле и класс Plugin в вашем основном приложении не совпадают, насколько это касается VM. Кастинг с «как плагин» возвращает значение null, потому что плагин! = Плагин. Как обойти это (за исключением того, что его можно использовать как объект или что-то еще), я не помню, но вы на правильном пути, исследуя класс ApplicationDomain. – joshtynjala

ответ

0

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

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

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

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 является ключевым здесь.Если вы ссылаетесь на docs:

собственное приложение погрузчика. Вы используете этот домен приложения при использовании ApplicationDomain.currentDomain. Когда нагрузка завершена, родительский и дочерний могут напрямую использовать классы друг друга. Если ребенок пытается определить класс с тем же именем, что и класс , уже определенный родителем, используется родительский класс , а класс игнорируется.