在父和子SWF之间共享类

时间:2011-08-13 13:19:56

标签: flash flex actionscript-3 applicationdomain

所以我有一种情况,我希望将一个类的对象从一个孩子传递给父母,说'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);

绝对没有用。 关于我能做什么的任何想法都能解决这个问题?

提前致谢

4 个答案:

答案 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中为类使用不同的名称或名称空间。