我目前正在尝试从标准 AS3 应用程序和 AIR 应用程序加载外部 SWF 文件。 AIR 应用程序的运行方式似乎与 Flash Player 运行的标准 SWF 的运行方式不同。
根据documentation , applicationDomain
LoaderContext
的属性(property)也可用于 AIR 应用程序,但它似乎不起作用。
我有以下代码:
package {
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.display.Sprite;
import flash.events.Event;
import flash.net.URLRequest;
import flash.system.ApplicationDomain;
import flash.system.LoaderContext;
public class Invoker extends Sprite
{
private var _ldr : Loader;
public function Invoker()
{
_ldr = new Loader();
_ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, onChildOneComplete);
var ldrC : LoaderContext = new LoaderContext(false,
new ApplicationDomain(ApplicationDomain.currentDomain)
);
_ldr.load(new URLRequest("otherSwf.swf"), ldrC);
}
private function onChildOneComplete(e : Event) : void
{
var c1ad : ApplicationDomain = (e.target as LoaderInfo).applicationDomain;
var inad : ApplicationDomain = ApplicationDomain.currentDomain;
trace("Child One parentDomain : " + c1ad.parentDomain);
trace("Invoker parentDomain : " + inad.parentDomain);
trace("Child One has Invoker : " + c1ad.hasDefinition("Invoker"));
trace("Invoker has Invoker : " + inad.hasDefinition("Invoker"));
}
}
}
将此代码编译为 SWF 文件并使用 Flash Player 启动它会执行以下输出,这似乎是正确的:
Child One parentDomain : [object ApplicationDomain]
Invoker parentDomain : null
Child One has Invoker : true
Invoker has Invoker : true
但是与 AIR 应用程序相同的代码会产生不同的输出:
Child One parentDomain : null
Invoker parentDomain : null
Child One has Invoker : false
Invoker has Invoker : true
根据文档,第一个输出(使用带有 Flash Player 的 SWF,而不是 AIR 应用程序)是正确的。此外,使用此代码段并将应用程序域更改为其他可能的配置(如
new ApplicationDomain(null)
或 ApplicationDomain.currentDomain
)确实符合文档对 SWF 的说明,但不会更改 AIR 应用程序的输出。任何线索为什么 AIR 只是忽略传递给加载程序上下文的应用程序域?有关此特定问题的任何文档?
非常感谢。
最佳答案
知道了。
该问题是由 SecurityDomain
中的不同行为引起的。 AIR 应用程序中的系统。在 AIR 应用程序中加载 SWF 文件时,它始终依赖于不同的沙箱。因此,AIR 创建了一个新的 SecurityDomain
对于这个 SWF。
自 SecurityDomain
是一组一个或多个 ApplicationDomain
s,这种行为迫使创建一个新的 ApplicationDomain
(在新的 SecurityDomain
中),忽略指定的(属于“主要” SecurityDomain
)。
有一个使用 URLLoader
的解决方法.从字节码加载时(使用 Loader.loadBytes
),SWF 加载到相同的 SecurityDomain
中.这就是为什么你必须把 allowLoadBytesCodeExecution
为真,因为它可能不安全。所以间接加载 SWF,首先通过 URLLoader
,然后用 Loader.loadBytes
,解决这个问题。
这是片段:
package {
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.display.Sprite;
import flash.events.Event;
import flash.net.URLLoader;
import flash.net.URLLoaderDataFormat;
import flash.net.URLRequest;
import flash.system.ApplicationDomain;
import flash.system.LoaderContext;
import flash.utils.ByteArray;
public class Invoker extends Sprite
{
public function Invoker()
{
var uldr : URLLoader = new URLLoader();
uldr.dataFormat = URLLoaderDataFormat.BINARY;
uldr.addEventListener(Event.COMPLETE, onBytesComplete);
uldr.load(new URLRequest("otherSwf.swf"));
}
private function onBytesComplete(e : Event) : void
{
var bytes : ByteArray = (e.target as URLLoader).data;
var ldr : Loader = new Loader();
ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, onChildComplete);
var ldrC : LoaderContext = new LoaderContext();
// This property was for AIR 1.0.
//ldrC.allowLoadBytesCodeExecution = true;
// Since AIR 2.0, it's allowCodeImport.
ldrC.allowCodeImport = true;
ldr.loadBytes(bytes, ldrC);
}
private function onChildComplete(e : Event) : void
{
var c1ad : ApplicationDomain = (e.target as LoaderInfo).applicationDomain;
var inad : ApplicationDomain = ApplicationDomain.currentDomain;
trace("Child One parentDomain : " + c1ad.parentDomain);
trace("Invoker parentDomain : " + inad.parentDomain);
trace("Child One has Invoker : " + c1ad.hasDefinition("Invoker"));
trace("Invoker has Invoker : " + inad.hasDefinition("Invoker"));
}
}
}
希望这可以帮助。
关于apache-flex - LoaderContext 和 ApplicationDomain 随 Adobe AIR 发生变化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/605791/