开发者

Error instantiating classes from runtime loaded swf

开发者 https://www.devze.com 2023-02-18 14:25 出处:网络
I have the following: protected function caller(event:FlexEvent):void { var r:URLRequest=new URLRequest(\'http://remote/TESTLibrary.swf\');

I have the following:

        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();
        }

And the class contained in the library:

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

If I comment definition of d:ArrayCollection eveything works fine but I u开发者_运维技巧se classes out of the global accessible package like mx.collections I get a VerifyError: Error #1014: Class mx.collections::ArrayCollection could not be found. Any help shall be very appreciated.


The type in this case was imported as you can see if you pay more attention to the old loader. however I wrote another way to load the swf which works great:

    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;
    }


The problem is your are referencing ArrayCollection without importing it first in the caller. I know exactly what you're trying to do - pull that class in at runtime for standard usage, but flash won't allow it like this. Without explicit reference to the class flash is forced to guess at what "ArrayCollection" is - so its throwing a verify error on compile. I tried this with a few different class types = and its standard behavior.

Note - if you instantiate the class in the callee - you can gain reference in the caller to a properly typed object:

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

but as soon as you reference it as its type in the caller, you get a verify error.

 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
            }

The solution is to import the type in the calling class. (Though I would love to see someone come up with a solution for this scenario that functions without the extra import... )

cheers!

0

精彩评论

暂无评论...
验证码 换一张
取 消