所以我有一种情况,我希望将一个类的对象从一个孩子传递给父母,说'MyBigAwesomeClass'。我将类定义导入父级和子级。
现在,如果我从相对于父级位置的位置加载子swf,一切都很好,但是当我使用完整的绝对路径加载它时,它会在父级中处理'BigAwesomeClass'的定义并且在子级中不同,并且不允许将“BigAwesomeClass”类型的对象分配给父类中的对象。
我感到非常难过,并且已经对ApplicationDomains感到头疼,包括使用此代码
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,swfLoaded);
var context:LoaderContext = new LoaderContext(false, ApplicationDomain.currentDomain);
loader.load(new URLRequest(_file.url),context);
绝对没有用。 关于我能做什么的任何想法都能解决这个问题?
提前致谢
答案 0 :(得分:1)
根据Adobe的文档(Loader#securityDomain):
为了使导入加载成功,加载的SWF文件的服务器 必须有一个信任加载SWF文件的域的策略文件。
诀窍是告诉Loader在加载swf时检查交叉域文件,在创建true
时将LoaderContext
作为第一个参数传递,例如:
var request:URLRequest = new URLRequest(_file.url);
var context:LoaderContext = new LoaderContext(true, null, SecurityDomain.currentDomain);
var loader:Loader = new Loader();
loader.load(request, context);
随附的跨域domain.xml应与子SWF位于同一位置,或位于其某个父文件夹中。 Here's a non-restrictive cross-domain file according to documentation from Adobe:
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM
"http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<site-control permitted-cross-domain-policies="all"/>
<allow-access-from domain="*" secure="false"/>
<allow-http-request-headers-from domain="*" headers="*" secure="false"/>
</cross-domain-policy>
另一个可能使您更容易的事情是传递接口而不是类,这将有效地绕过冲突的代码。这将起作用,因为子节点在运行时默认从父类继承接口(参见Loader#applicationDomain点#1)。然后子类可以安全地实例化每个对象的自己版本,只要该对象遵循该接口即可。例如:
var applicationDomain:ApplicationDomain = loader.contextLoaderInfo.applicationDomain;
var classDefinition:Class = applicationDomain.getDefinition("MyBigAwesomeClass") as class;
var instance:IMyBigAwesomeInterface = new classDefinition() as IMyByAwesomeInterface;
MyBigAwesomeClass的定义如下所示:
public class MyBigAwesomeClass implements IMyBigAwesomeInterface
{
...
}
答案 1 :(得分:1)
好吧,事实证明它是一个沙盒问题。不属于安装程序的文件放在不同的安全沙箱中,由于它们位于不同的沙箱中,因此导入到父项中的子项不会继承ApplicationDomain
中父项的定义和两个单独的定义存在不相容的。可悲的是,似乎没有直接的解决方法。 Adobe允许通过SandBoxBridge在沙箱之间进行通信,但这会强制您使用对象类型,这种方式会破坏整个事物的目的。据我所知,两个不同沙箱中的类没有办法兼容,即使它们完全相同。我想它背后是没有用Objects严格打字的痛苦世界。
答案 2 :(得分:0)
我同意你的看法,这个问题可能与父母有关。孩子的应用程序域,但为了更准确地回答,最好有一些示例使用你想在父母和孩子之间分享的课程。
从理论上讲,如果为孩子定义了一个班级,似乎可以避免这个问题......这是一个非常基本的例子,在我看来,无论你从哪儿开车,都应该有效。
package com.example.test { public class Parent extends Sprite { private var child:Child; private var shared:SharedClass = new SharedClass(); public function Parent() { loadChild(); } private function loadChild():void { // load process } private function loadComplete(event:Event):void { child = event.currentTarget.content as Child; if( child != null ) shared = child.shared; // remove event etc... } } } package com.example.test { public class Child extends Sprite { // I use a public var here , but you can use a getter... public var shared:SharedClass; public function Child() { shared = new SharedClass(); } } } package com.example.test { public class SharedClass { public function SharedClass() { trace('Hello from Shared Class'); } } }
答案 3 :(得分:0)
一种选择是在子类中使用实现方法,使用它自己的applicationDomain返回类的实例,例如:
public class Child extends Sprite implements IMyBigAwesomeClassLoader
{
public function getMyByigAwesomeClass():IMyBigAwesomeClass
{
var classDefinition:Class = applicationDomain.getDefinition("MyBigAwesomeClass");
var instance:IMyBigAwesomeClass = new classDefinition() as IMyBigAwesomeClass;
return instance;
}
}
IMyBigAwesomeClassLoader
看起来像这样:
public interface IMyBigAwesomeClass
{
function getMyBigAwesomeClass():IMyBigAwesomeClass;
}
然后父剪辑将使用它来从子节点加载实例:
public function loadCompleteHandler(event:Event):void
{
var myBigAwesomeClassLoader:IMyBigAwesomeClassLoader = (event.target as Loader).content as IMyBigAwesomeClass;
myBigAwesomeClass = myBigAwesomeClassLoader.getMyBigAwesomeClass();
}
这里使用接口的原因是将类定义与其实现分离。尽管父SWF和子SWF中的类具有相同的名称,但Flash将它们视为不同的类。界面告诉Flash,即使它们不同,它们也可以以相同的方式使用。
Flash使用静态类型,这意味着一旦定义了类,它就永远不会改变,这意味着它永远不会用另一个类覆盖一个类定义。因此,如果有两个具有相同名称的类,则必须使用getDefinition
来解决冲突的名称。如果要避免这种增加的复杂性,可以在父SWF和子SWF中为类使用不同的名称或名称空间。