LoaderContextとApplicationDomainはAdobe AIRで変更されますか?
-
03-07-2019 - |
質問
現在、標準のAS3アプリケーションとAIRアプリケーションの両方から外部SWFファイルをロードする実験を行っています。 AIRアプリケーションは、Flash Playerで実行される標準のSWFと同じようには動作しないようです。
ドキュメントによると、 LoaderContext
の applicationDomain
プロパティは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
ドキュメントによると、最初の出力(AIRアプリケーションではなく、Flash PlayerでSWFを使用)が正しい出力です。また、このスニペットで遊んで、アプリケーションドメインを他の可能な構成( new ApplicationDomain(null)
、または ApplicationDomain.currentDomain
など)に変更すると、ドキュメントに記載されているとおりのことが行われますSWF。ただし、AIRアプリケーションの出力は変更されません。
AIRが単にローダーコンテキストに渡されたアプリケーションドメインを無視している理由は何ですか?この特定の問題に関するドキュメントはありますか?
ありがとうございます。
解決
了解。
この問題は、AIRアプリケーション内の SecurityDomain
システムの動作が異なるために発生しました。 SWFファイルがAIRアプリケーション内にロードされると、常に異なるサンドボックスに依存します。したがって、AIRはこのSWFの新しい SecurityDomain
を作成します。
SecurityDomain
は1つ以上の ApplicationDomain
のグループであるため、この動作により、新しい ApplicationDomain
(新しい SecurityDomain
)、指定されたもの(「メイン」 SecurityDomain
に属する)を無視します。
URLLoader
を使用する回避策があります。バイトコードから( Loader.loadBytes
を使用して)ロードすると、SWFは同じ SecurityDomain
内にロードされます。安全でない可能性があるため、 allowLoadBytesCodeExecution
をtrueに設定する必要があるのはこのためです。したがって、最初に URLLoader
を使用してSWFを間接的にロードし、次に 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"));
}
}
}
これがお役に立てば幸いです。
他のヒント
それは良いものです、ありがとう:)
もう1つの詳細: allowLoadBytesCodeExecution はレガシープロパティになり、AIR 1.0で定義されました。 AIR 2.0では、代わりに allowCodeImport を使用します。
ciao、 PG