Ошибка создания экземпляров классов из загруженного SWF во время выполнения - PullRequest
1 голос
/ 21 марта 2011

У меня есть следующее:

        protected function caller(event:FlexEvent):void
        {
            var r:URLRequest=new URLRequest('http://remote/TESTLibrary.swf');
            var c:LoaderContext=new LoaderContext();
            c.applicationDomain=ApplicationDomain.currentDomain;
            var l:Loader=new Loader();
            l.contentLoaderInfo.addEventListener(Event.COMPLETE, hndComplete);
            l.load(r, c);
        }


        protected function hndComplete(event:Event):void
        {
            var d:ArrayCollection; //not used but here for
            var cls:Class=(event.target as LoaderInfo).applicationDomain.getDefinition('ro.vnc.modules.ModuleManager') as Class;
            var instance:Object=new cls();
        }

И класс, содержащийся в библиотеке:

package ro.vnc.modules
{
    import mx.collections.ArrayCollection;

    public class ModuleManager
    {
        public function ModuleManager()
        {
            var d:ArrayCollection;//if commented works fine
            var c:Number=5;
            trace('ModuleManager', c);
        }
    }
}

Если я прокомментирую определение d: ArrayCollection все работает нормально, но я использую классы внеиз глобального доступного пакета, такого как mx.collections, я получаю VerifyError: Ошибка # 1014: класс mx.collections :: ArrayCollection не найден.Любая помощь очень ценится.

Ответы [ 2 ]

1 голос
/ 25 марта 2011

Тип в этом случае был импортирован, как вы можете видеть, если вы обращаете больше внимания на старый загрузчик. Однако я написал другой способ загрузить SWF, который прекрасно работает:

    public function ModulesInstaller()
    {
        var f:File=new File();

        f.addEventListener(Event.SELECT, hndSelect);
        f.browseForOpen('Select Library', [new FileFilter('Library file', '*.swf')]);
    }


    protected function hndSelect(event:Event):void
    {
        var fs:FileStream=new FileStream();
        fs.open(event.target as File, FileMode.READ);
        var bytes:ByteArray=new ByteArray();
        fs.readBytes(bytes);
        var lc:LoaderContext=new LoaderContext();
        lc.allowCodeImport=true;
        var l:Loader=new Loader();
        l.contentLoaderInfo.addEventListener(Event.INIT, hndLoaded);
        l.loadBytes(bytes, lc);
        l.loaderInfo

    }

    private function hndLoaded(event:Event):void
    {
            var clsRef:Class=(event.target as LoaderInfo).applicationDomain.getDefinition('classRefName') as Class;
    }
0 голосов
/ 21 марта 2011

Проблема в том, что вы ссылаетесь на ArrayCollection, не импортируя его сначала в вызывающую программу. Я точно знаю, что вы пытаетесь сделать - включить этот класс во время выполнения для стандартного использования, но Flash не допустит этого. Без явной ссылки на класс flash вынужден угадывать, что такое «ArrayCollection» - поэтому выдает ошибку проверки при компиляции. Я попробовал это с несколькими различными типами классов = и его стандартным поведением.

Примечание - если вы создаете экземпляр класса в вызываемом объекте - вы можете получить ссылку в вызывающем объекте на правильно типизированный объект:

package ro.vnc.modules
{
    import mx.collections.ArrayCollection;

    public class ModuleManager
    {

        public var d:ArrayCollection;

        public function ModuleManager()
        {
            d = new ArrayCollection();
            var c:Number=5;
            trace('ModuleManager', c);
        }
    }
}

, но как только вы указываете его как тип в вызывающей программе, вы получаете ошибку проверки.

 protected function hndComplete(event:Event):void
            {
                var cls:Class=(event.target as LoaderInfo).applicationDomain.getDefinition('ro.vnc.modules.ModuleManager') as Class;
                var instance:Object=new cls();
                trace(instance.d); //[object ArrayCollection]
                var d1:ArrayCollection = instance.d; // throws verify error
                var d2:* = (event.target as LoaderInfo).applicationDomain.getDefinition(instance.d); // throws reference error
            }

Решение состоит в том, чтобы импортировать тип в вызывающем классе. (Хотя я бы хотел, чтобы кто-то придумал решение для этого сценария, которое работает без дополнительного импорта ...)

ура!

...