0

我正在尝试使用接口加载远程 SWF 并访问它的方法和属性。(这里有一个类似的问题,就“这很奇怪!”但没有解决:Loading swf and using it through interface

我的远程 SWF 如下所示:

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

然后我有一个如下所示的界面:

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

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

最后,我有一个加载器类,它下拉 SWF 并尝试将其转换为远程 SWF 实现的相同接口。编辑 - 道歉的长度,被要求发布完整的来源:

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() 将触发)。但是,一旦我将其转换为界面,它就会失败。

有任何想法吗?

编辑

好的,我在两个应用程序之间共享的自定义事件类中遇到了同样的问题。Flash 错误,说它不能从一个类转换到另一个类——即使它们是相同的,它们在不同的项目中,所以我想象不同的命名空间。我认为加载到同一个 applicationDomain 会解决这个问题,但事实并非如此。有没有其他方法可以在不求助于公共图书馆/SWC 或类似的情况下解决这个问题?

4

1 回答 1

1

我认为这可能是应用程序域的问题。加载的 SWF 驻留在其自己的应用程序域中,因此它不共享完全相同的接口。尝试使用applicationDomain加载器的 LoaderInfo 对象的属性将 swf 加载到»当前应用程序域«。

这里

祝你好运……</p>

编辑::

它必须在加载程序加载方法中完成

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

这里

编辑 2::

一旦我遇到一个更奇怪的错误,这是由于我创建了一个接口,编译了»加载文件«和»加载的文件«,通过添加方法更改了接口并忘记编译»to加载文件«(有很多)。也许发生了这样的事情……</p>

编辑 3::

如果我没记错的话,必须等待Event.INIT加载 swf 的事件,在此事件之后,加载的 swf 的构造函数首先运行。

编辑 4::

找到这个,也许你需要做:

var YourInterfaceClass:Class = ApplicationDomain.currentDomain.getDefinition( "YourInterface" ) as Class; 
var myInstance:YourINterface = event.target.content as YourInterface; 
于 2012-11-12T16:41:55.023 回答