Actionscript 3 将加载的SWF转换为接口
我试图加载一个远程SWF,并使用一个接口访问它的方法和属性。(这里有一个类似的问题,甚至到了“这很奇怪!”的地步,但没有解决:) 我的远程SWF如下所示:Actionscript 3 将加载的SWF转换为接口,actionscript-3,flash,casting,Actionscript 3,Flash,Casting,我试图加载一个远程SWF,并使用一个接口访问它的方法和属性。(这里有一个类似的问题,甚至到了“这很奇怪!”的地步,但没有解决:) 我的远程SWF如下所示: package { import flash.display.Sprite; import flash.events.Event; import flash.system.Security; import IMultiplayer; [SWF(width="238", height="60"
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;
}
}
然后,我有一个如下所示的界面:
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;
}
}
最后,我得到了一个loader类,它拉下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错误,说它不能从一个类转换到另一个类——即使它们是相同的,但它们在不同的项目中,所以我想象不同的名称空间。我假设加载到同一个应用程序域可以解决这个问题,但事实并非如此。有没有其他方法可以避免使用公共库/SWC或类似工具?我认为这可能是应用程序领域的问题。加载的SWF驻留在自己的应用程序域中,因此它不共享完全相同的接口。尝试使用加载程序的LoaderInfo对象的
applicationDomain
属性将swf加载到»当前应用程序域«
看
祝你好运
编辑::
必须在装载机装载方法中完成
var context:LoaderContext = new LoaderContext(false, ApplicationDomain.currentDomain);
var loader:Loader = new Loader();
loader.load(new URLRequest("myButtons.swf"), context);
从
编辑2::
一旦我遇到一个更奇怪的错误,这是因为我创建了一个接口,编译了»加载文件«和»加载文件«的文件,通过添加一个方法更改了接口,忘记了编译»加载文件«(有很多)。也许发生了这样的事情
编辑3::
如果我没记错的话,人们必须等待加载的swf的Event.INIT
事件,在该事件之后,加载的swf的构造函数首先运行
编辑4::
发现时,您可能需要执行以下操作:
var YourInterfaceClass:Class = ApplicationDomain.currentDomain.getDefinition( "YourInterface" ) as Class;
var myInstance:YourINterface = event.target.content as YourInterface;
是的,基本上我就是这么想的。根本不起作用,只要我将其转换到接口,它就会返回null。这简直快把我逼疯了!以上代码是否是您用于加载的完整代码?错误消息是什么?嗯…上次我这么做时,我没有安全沙箱的问题,但是如果违反的文件不会加载…我将加载的内容转换为:Myinterface(load.content),但这与»as«语法相同。我现在看到的唯一区别是,我使用Event.INIT事件侦听加载端。但如果强制转换失败,这表明这两种数据类型不相同,在这种情况下,它们可能位于应用程序域的不同名称空间中。您可以尝试将IMultiplayer接口放置在与默认ns.Cast方法不同的命名空间中。Cast方法只有一个。使用“as”,第二种方法是转换。无论如何,您应该检查“IMultiplayer”接口是否与加载的SWF中的类型相同,这样您就知道问题出在哪里了。使用带有“getDefinition”的代码来比较此接口。结果表明,它既与applicationDomain有关,也与两端的接口尽管功能相同,但具有不同的包这一事实有关。现在工作很有魅力,谢谢你的帮助!