铸造加载的SWF作为一个接口 [英] Casting a loaded SWF as an interface

查看:139
本文介绍了铸造加载的SWF作为一个接口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图加载远程SWF和访问它的方法和属性,使用接口。 (这里有一个类似的问题,进行了尽可能这是不可思议!,但并没有解决这个问题:的加载SWF和使用它通过接口)

I'm trying to load in a remote SWF and access it's methods and properties, using an interface. (There's a similar question here that got as far as "that's weird!" but didn't resolve it: Loading swf and using it through interface)

我的远程SWF看起来是这样的:

My remote SWF looks like this:

package 
{   
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.system.Security;

    import IMultiplayer;

    [SWF(width="238", height="60", frameRate="60", backgroundColor="#FFFFFF")]
    public class Main extends Sprite implements IMultiplayer
    {
        public function init(e:Event):void
        {

        }

        public function TEST():void
        {
            trace("TEST()");
        }   
    }
}

然后我有一个看起来像这样的接口:

I then have an interface that looks like this:

package
{
    import flash.events.*;
    import flash.display.*;

    public interface IMultiplayer
    {
        function init(e:Event):void;
        function TEST():void;
    }
}

最后,我已经得到了拉下SWF,并试图将它转换为相同的界面,远程SWF实现了一个Loader类。编辑 - 歉意长,被要求张贴完整的源代码:

And finally, I've got a loader class that pulls down the SWF and tries to cast it as the same interface that the remote SWF implements. EDIT - apologies for length, was asked to post the full source:

package uk.co.MyDomain
{
    import flash.display.DisplayObject;
    import flash.display.Loader;
    import flash.display.LoaderInfo;
    import flash.display.MovieClip;
    import flash.display.Sprite;
    import flash.events.ErrorEvent;
    import flash.events.Event;
    import flash.events.EventDispatcher;
    import flash.events.IEventDispatcher;
    import flash.events.IOErrorEvent;
    import flash.events.TimerEvent;
    import flash.net.URLRequest;
    import flash.system.ApplicationDomain;
    import flash.system.LoaderContext;
    import flash.system.Security;
    import flash.system.SecurityDomain;
    import flash.utils.Timer;

    import uk.co.MyDomain.*;

    import utils.Console;

    public class MultiplayerLoader extends Sprite
    {
        private var ld:Loader;
        private var _environment:String;
        public var _mpInstance:IMultiplayer;

        private const SANDBOX_SWF:String = "http://static.sandbox.dev.MyDomain.co.uk/smartfoxtest/dev/swf/MP.swf";

        public function MultiplayerLoader(environment:String)
        {
            _environment = environment;
        }

        public function loadMultiplayer():void
        {
            ld = new Loader();

            var context:LoaderContext = new LoaderContext(false, ApplicationDomain.currentDomain);

            ld.contentLoaderInfo.addEventListener(Event.COMPLETE, multiplayerLoaded);
            ld.contentLoaderInfo.addEventListener(ErrorEvent.ERROR, onLoadError);
            ld.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onIOLoadError);
            ld.contentLoaderInfo.addEventListener(IOErrorEvent.DISK_ERROR, onDiskError);
            ld.contentLoaderInfo.addEventListener(IOErrorEvent.NETWORK_ERROR, onNetworkError);
            ld.contentLoaderInfo.addEventListener(IOErrorEvent.VERIFY_ERROR, onVerifyError);

            if(Security.sandboxType == Security.REMOTE)
            {
                trace('[MP Loader] Loading with context');
                ld.load(new URLRequest(SANDBOX_SWF), context);      
            }
            else
            {
                trace('[MP Loader] Loading with NO context');
                ld.load(new URLRequest(SANDBOX_SWF));   
            }
        }

        private function onIOLoadError(e:IOErrorEvent):void
        {
            notifyFailure('IOLoadError');
        }

        private function onDiskError(e:IOErrorEvent):void
        {
            notifyFailure('IOLoadError');
        }

        private function onNetworkError(e:IOErrorEvent):void
        {
            notifyFailure('IOLoadError');
        }

        private function onVerifyError(e:IOErrorEvent):void
        {
            notifyFailure('IOLoadError');
        }

        private function onLoadError(e:ErrorEvent):void
        {
            notifyFailure('IOLoadError');
        }

        private function multiplayerLoaded(e:Event):void
        {   
            var tester:IMultiplayer = e.currentTarget.content as IMultiplayer;          
            Console.log('Loaded: ' + tester);

            dispatchEvent(new MultiplayerEvent(MultiplayerEvent.SWF_LOAD_SUCCESS)); 
        }

        private function notifyFailure(reason:String):void
        {
            var failEvent:MultiplayerEvent = new MultiplayerEvent(MultiplayerEvent.SWF_LOAD_FAILURE);
            failEvent.params = {'reason':reason}

            dispatchEvent(failEvent);
        }
    }
}

现在,如果我不投它使用的接口,我可以跟踪它成功和调用函数(因此e.target.content.TEST()将触发)。然而,当我投它的接口,它失败。

Now, if I DON'T cast it to use the interface, I can trace it out successfully and call functions (so e.target.content.TEST() will fire). However, as soon as I cast it to the interface, it fails.

任何想法?

修改

OK,我收到与既是应用程序之间共享一个自定义事件类相同的问题。闪存错误,说,它不能从一个类转换到另 - 即使它们是相同的,他们是在不同的项目,所以我想不同的命名空间。我以为,装成于同一ApplicationDomain会解决这个问题,但它不是。有没有其他办法可以解决这个问题,而不诉诸公用库/ SWC或相似?

OK, I'm getting the same issue with a custom event class that's shared between both applications. Flash errors, saying it cannot convert from one class to the other - even though they're identical they're in different projects, and so I imagine different namespaces. I assumed that loading into the same applicationDomain would fix this, but it hasn't. Is there any other way I can get around this without resorting to a common library/SWC or similar?

推荐答案

我想这可能是应用领域的问题。加载的SWF驻留在其自己的应用领域,因此不共享完全相同的接口。尝试加载SWF到»当前应用程序域«,​​通过装载的LoaderInfo对象的的applicationDomain 属性。

I think this might be an issue of the application domain. The loaded SWF resides in its own application domain so it does not share the exact same interface. Try to load the swf into the »current application domain«, using the applicationDomainproperty of the Loader's LoaderInfo Object.

看<一href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/system/LoaderContext.html"相对=nofollow>这里

好运...

:

它必须在装载机完成加载方法

it has to be done in the loaders load method

var context:LoaderContext = new LoaderContext(false, ApplicationDomain.currentDomain);
var loader:Loader = new Loader();
loader.load(new URLRequest("myButtons.swf"), context);

从这里

from here

编辑2 ::

有一次,我遇到了一个更奇怪的错误,它是由我创建一个接口,编译»加载文件«与加载«»文件,通过添加一个方法改变了界面和忘记编译造成的事实该»加载文件«(有很多)。也许发生了这样的事情...

Once I ran into an even more strange error, it was caused by the fact that i created an interface, compiled the »to load files« and »file that loaded«, changed the interface through adding a method and forgot to compile the »to load files« (there were a lot). Perhaps happened something like this…

编辑3 ::

如果我记得没错比人们必须等待加载的SWF的 Event.INIT 时,首先这个事件后,加载的SWF的构造跑了。

If I remember right than one has to wait for the Event.INIT event of loaded swf's, first after this event the constructor of the loaded swf ran.

编辑4 ::

这个,也许你需要做的:

var YourInterfaceClass:Class = ApplicationDomain.currentDomain.getDefinition( "YourInterface" ) as Class; 
var myInstance:YourINterface = event.target.content as YourInterface; 

这篇关于铸造加载的SWF作为一个接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆